/*Payload

    TODO
    - PWM para sevo
    - Modo monitoreo
    - Revisar que se entre solamente una vez a las conversiones y operaciones realizadas antes de la transmision
        y las banderas no permiten que se entre de nuevo a pesar de ya haberlas realizado una vez.
    - Actualizar PACKET ALOCATION and Calculation para Payload y Container y enviarlas a Luttman y Ana Silvia
    - Implementar PROCESSOR RESET RECOVERY
    - Analizar implementacion de autodesbloque de segmento A en funciones de FlashWrite
    - Funcionamiento de memoria I2C
    - Configurar RTC
    - Arreglar conversion ASCII de acelerometro para soportar numeros negativos*
    - Asegurar que GIE esta siempre habilitado
    - Verificar qué sucede cuando hay un evento fuera del tiempo de ejecución de todas las funciones de FSW, es decir,
      durante el tiempo que tendría que estar en modo SLEEP. Podría ser que se ejecuten funciones cuya unica condicion
      para ejecutarse es revisar si un dato aun no esta listo.
    - Modoficar startXBEETransmission para aceptar parametros de Datos_a_enviar y longitud_de_datos y asi pueda
      funcionar enviado a XBEE cualquier paquete, no solo el formato de PFSW_TransPackage  02/03/2014
    - Corregir funcionamiento cuando se pierden datos o no se reciben por I2C con NACK 02/03/2014
    - Arreglar llamada a TA0CCR1 y añadir funcion para llamada del mismo 03/03/2014
    - Subir frecuencia del CPU a 16MHz
*/



#include <msp430F5529.h>

#define VOLTAGE_OFFSET          28
#define TEST_SENSOR_OFFSET      33
#define TEMP_SENSOR_OFFSET      22
#define PRES_SENSOR_OFFSET      16
#define ACC_X_OFFSET            34
#define ACC_Y_OFFSET            39
#define ACC_Z_OFFSET            44
#define PACKET_COUNT_OFFSET     6
#define MISSION_TIME_OFFSET     11

#define TEST_SENSOR_ADDRESS     0x04
#define ACC_SENSOR_ADDRESS      0x53
#define BMP085_ADDRESS          0x77
#define DS1307_ADDRESS          0x68
#define EXTERNAL_MEMORY_ADDRESS  0x50
#define RTC_ADDRESS             0x6F

#define FLASH_INFO_SEGMENT_A         0x1980
#define FLASH_INFO_SEGMENT_B         0x1900
#define FLASH_INFO_SEGMENT_C         0x1880
#define FLASH_INFO_SEGMENT_D         0x1800


/*
    EXTERNAL MEMORY DATA ORGANIZATION

    ADDRESS                     DATA                                  DATA
    0x0000:0x0001               NextWritableAddress for packet data   [MSB:LSB]
    0x0002:0x0003               Mission Time                          [MSB:LSB]
    0x0004:0x0005               PacketCount                           [MSB:LSB]
    0x0006                      CFSW State                            One byte
    0x0007:0x000A               LastPressure                          [MSB:LSB] This is a 4 byte variable (long)
    0x000B:0x3FFF               DATA PACKETS                          See CFSW_Tanspackage

*/


#define NEXT_AVAILABLE_EEPROM_ADDRESS     0x0000
#define FIRST_AVAILABLE_EEPROM_ADDRESS    0x000B        
#define MISSION_TIME_EEPROM_ADDRESS       0x0002
#define PACKET_COUNT_EEPROM_ADDRESS       0x0004
#define CFSW_STATE_EEPROM_ADDRESS         0x0006
#define LAST_PRESSURE_EEPROM_ADDRESS      0x0007    

#define TELEMETRY_DATAPACKET_LENGTH   46

#define RTC_SQWE  0x40
#define RTC_MFP_1HZ 0x00
#define RTC_START 0x80   


unsigned char modo = 0x55;



unsigned char PFSW_TransPackage[52] =// PLD  |      TEAM ID          |     |     PACKET COUNT       |  
                                     // ADDR |  1      2    3      4 |  ,  |  1      2     3     4  |
                                        {0x88, 0x32,  0x36, 0x35, 0x33, 0x2C, 0x33, 0x32,  0x35, 0x30,
                                     // |    |    MISSION TIME       |      |        PRESSURE SENSOR        |     |        TEMP_SENSOR         | 
                                     // |  , |  1     2     3     4  |    , |   1     2     3     4     5   |  ,  |   1    2    3     4     5  |   
                                         0x2C, 0x32, 0x35, 0x30, 0x30,  0x2C,  0x31, 0x30, 0x30, 0x30, 0x30, 0x2C, 0x32, 0x35, 0x34, 0x36, 0x37, 
                                     // |     |     VOLTAGE          |      |            ACCELERATION_SENSOR
                                     // | ,   |  1    .     2      3 |   ,  |  +-    X1    X2    X3    X4    +-    Y1    Y2   Y3     Y4    +-    Z1
                                         0x2C, 0x33, 0x2E, 0x33, 0x32,  0x2C, 0x42, 0x30, 0x31, 0x32, 0x33, 0x42, 0x33, 0x34, 0x35, 0x36, 0x42, 0x36,
                                     //                   |    | PFCS_STAT |       |
                                     //  Z2     Z3    Z4  |  , |  1     2  |   /r  |     
                                         0x37, 0x38, 0x39, 0x2C, 0x46, 0x30,  0x0D };



unsigned char PFSW_TransPackage_Length = 52;


/*    --------      XBEE RECEIVE VARIABLES   --------- */
unsigned char XBEE_RXBUF[64] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                0,0,0,0}; // Almacena el dato recibido en el BUFFER
                                          // de recepcion UART de XBEE

unsigned char XBEE_RXBUF_POINTER = 0;   // Indica la posicion del ultimo byte recibido
                                        // por XBEE_RX almacenado en XBEE_RXBUF

/*    --------      XBEE TRANSMIT VARIABLES      -------- */
unsigned char *XBEE_TXBUF = 0;        // Apunta a la siguiente cadena de datos a ser 
                                      // enviada a XBEE por UART

unsigned char XBEE_TXBUF_LENGTH = 0;  //Almacena la longitud de los datos a ser
                                      //enviados a XBEE por UART

unsigned char XBEE_TXBUF_POINTER = 0; //Apunta al siguiente byte en 
                                      //XBEE_TXBUF a ser enviado

unsigned int XBEE_TXBUF_COUNTER = 0;  // LLeva la cuenta de la cantidad de paquetes enviados a XBEE

/*  ------------  CUENTA DE PAQUETES ----------------- */

unsigned char XBEE_PACKET_SAVE_PROC = 0;

unsigned char XBEE_PACKET_RETRIEVE_PROC = 0;



/*    --------  PC RECEIVE VARIABLES  --------    */

unsigned char PC_RXBUF[64] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                              0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                              0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                              0,0,0,0};  // Almacena datos recibidos desde PC

unsigned char PC_RXBUF_POINTER = 0;     // Indica la posicion del ultimo byte recibo desde PC
                                        // y almacenado en  PC_RXBUF

/*    -------- PC TRANSMIT VARIABLES  --------     */
unsigned char *PC_TXBUF = 0;            // Apunta a la siguiente cadena de datos a ser 
                                        // enviada por PC UART
unsigned char PC_TXBUF_LENGTH = 0;      // Almacena la longitud de datos a ser enviados
                                        // por PC UART
unsigned char PC_TXBUF_POINTER = 0;     // Apunta al siguiente byte en
                                        // PC_TXBUF a ser enviado
unsigned int PC_TXBUF_COUNTER = 0;      // Cuenta la cantidad de paquete enviados a PC

unsigned char PC_PACKET[40]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};





/*    --------     I2C SENSOR BUS TRANSMIT VARIABLES ------- */
unsigned char  *SENSOR_TXBUF = 0;

unsigned char  SENSOR_TXBUF_LENGTH = 0;

unsigned char  SENSOR_TXBUF_POINTER = 0;

unsigned char  SENSOR_RXBUF[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

unsigned char SENSOR_RXBUF_POINTER = 0;
unsigned char  SENSOR_RX_EXPECTED = 0;
unsigned char SENSOR_TX_BUFFER[10] = {0,0,0,0,0,0,0,0,0,0};



/*    -------    VOLTAGE SENSOR VARIABLES     --------   */
unsigned int VOLTAJE_ADC = 0;         // Almacena la conversion analogico-digital del sensor de
                                      // de voltaje en formato binario



/*    ------- ACCELERATION SENSOR DATA ------ */
unsigned char ACC_SENSOR_PROCESS_STATE = 0;

unsigned char ACC_SENSOR_CONF_DATA[6] = {0x31, 0x0B, 0x2E, 0x08, 0x2E, 0x80}; 

unsigned char ACC_SENSOR_CONF_DATALENGTH = 6;

unsigned char ACC_SENSOR_CONF_PROCESS_STATE = 0;


unsigned char ACC_SENSOR_DATA_FORMAT[2] = {0x31,0x01};
unsigned char ACC_SENSOR_POWER_CTL[2] = {0x2D,0x08};
unsigned char ACC_SENSOR_DATA_ADDRESS[6] = {0x32,0x33, 0x34, 0x35, 0x36, 0x37};

unsigned char ACC_SENSOR_DATA[6]= {0,0,0,0,0,0};

int ACC_SENSOR_X = 0;
int ACC_SENSOR_Y = 0;
int ACC_SENSOR_Z = 0;


unsigned char ACC_SENSOR_DATAX0 = 0x32;
unsigned char ACC_SENSOR_DATAX1 = 0x33;
unsigned char ACC_SENSOR_DATAY0 = 0x34;
unsigned char ACC_SENSOR_DATAY1 = 0x35;
unsigned char ACC_SENSOR_DATAZ0 = 0x36;
unsigned char ACC_SENSOR_DATAZ1 = 0x37;



/*    ---------  BMP085 VARIABLES ----------  */
unsigned const char BMP085_OSS = 0;
unsigned char BMP085_CAL_PROCESS_STATE = 0;

unsigned char BMP085_CAL_DATA_ADDRESS[22] = {0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1,0xB2, 
                                             0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 
                                             0xBC, 0xBD, 0xBE, 0xBF};



    /*    --- BMP085 TEMPERATURE VARIABLES ----    */
unsigned char BMP085_UT_PROCESS_STATE = 0;
unsigned char BMP085_UT_DATA[2]= {0xF4, 0x2E};
unsigned char BMP085_UT_DATA_ADDRESS[3] = {0xF6, 0xF7};
unsigned int BMP085_UT = 0;


    /*   ---- BMP085 PRESSURE VARIABLES ----  */
unsigned char BMP085_UP_MSB = 0;
unsigned char BMP085_UP_LSB = 0;
unsigned char BMP085_UP_XLSB = 0;
unsigned char BMP085_UP_DATA[2] = {0xF4, 0x34};
unsigned char BMP085_UP_DATA_ADDRESS[3] = {0xF6, 0xF7, 0xF8};
unsigned long BMP085_UP = 0;
unsigned char BMP085_UP_PROCESS_STATE = 0;

/*     --------   FLASH MEMORY VARIABLES ------   */

unsigned char SEGMENT_INFOA_COUNTER = 0;                // Cuenta el numero de veces que se ha escrito a Segmento INFO A

unsigned char calibratingSensor = 0;   

/*
    calibratingSensor 
    BIT       Estado      Descripcion
    0         0           Calibracion BMP085 no ejecutandose
              1           Calibración BMP085 ejecutandose
    1         0           Calibración ADXL345 no ejecutandose
              1           Calibración ADXL345 ejecutandose

*/


   /* -----  BMP085 CALIBRATION DATA ------ */

int ac1 = 0;
int ac2 = 0;
int ac3 = 0;

unsigned int ac4 = 0;
unsigned int ac5 = 0;
unsigned int ac6 = 0;

int b1 = 0;
int b2 = 0;
int mb = 0;
int mc = 0;
int md = 0;

/*  ------ PROCESS FLAGS ------  */

unsigned char LowPowerFlags = 0;
/*
  LowPowerFlags
    BIT      Estado             Descripcion
    0         0                 No entrar a modo Lowpower
              1                 Entrar a modo Lowpower
    1         0                 I2C TX NO permite entrar a LPM
              1                 I2C TX SI permite entrar a LPM
    2         0                 XBEE TX NO permite LPM
              1                 XBEE TX SI permite LPM
    3         0                 I2C RX No permite entrar a LPM
              1                 I2C RX SI permite entrar a LPM
    4         0                 TA0CCR2 NO permite LPM
              1                 TA0CCR2 Permite LPM
    5         0                 TA0CCR1 No permite LPM
              1                 TA0CCR1 Permite LPM
    6         0                 TA0CCR3 No permite LPM
              1                 TA0CCR3 Permite LPM
    7         0                 TA0CCR4 No permite LPM
              1                 TA0CCR4 Permite LPM
*/

unsigned char LowPowerFlags2 = 0;

/*

    LowPowerFlags2
    BIT         Estado          Descripcion
    0           0               TA1CCR1 No permite LPM
                1               TA1CRR1 permite LPM
    1           0               TA1CCR2 No permite LPM
                1               TA1CCR2 permite LPM
    2           0               TA2CCR1 no permite LPM
                1               TA2CCR1 permite LPM                  

*/

unsigned char Flags1 = 0;
/*
  Flags 1
    BIT       Estado       Descripcion
    0           0            No se ha recibido nada por UCA0RXBUF
                1            Se recibio dato por UCA0RXBUF
    1           0            No iniciar transmision por UCA0TXBUF
                1            Iniciar transmision por UCA0TXBUF
    2           0            No Habilitar conversion de ADC
                1            Habilitar conversion ADC
    3           0            Voltaje no listo en paquete
                1            Voltaje listo en paquete
    4           0            Transmision no esta en curso
                1            Transmision en curso
    5           0            XBEE No  disponible (sleep)
                1            XBEE disponible 
    6           0            No iniciar conversion BMP085 temperatura
                1            Iniciar conversion BMP085 temperatura
    7           0            No iniciar conversion BMP085 presion
                1            Iniciar conversion BMP085 presion

*/

unsigned char Flags2 = 0;
/*
  Flags 2
    BIT      Estado       Descripcion
    0           0            No hacer conversion binario-ASCII de voltaje
                1            Hacer conversion binario-ASCII de voltaje, DATO LISTO
    1           0            No hacer conversion binario-ASCII de test-sensor
                1            Hacer conversion, DATO LISTO
    2           0            No hacer conversion binario-ASCII DE Temperatura
                1            Hacer binario-ASCII de  temperatura
    3           0            No hacer conversion binario-ASCII de Presion
                1            Hacer conversion binario-ASCII de Presion 
    4           0            Muestra de ACC Sensor NO Lista
                1            Muestra de ACC Sensor Lista
    5           0            No iniciar muestre de ACC Sensor
                1            Iniciar muestreo de ACC Sensor
*/

unsigned char Flags3 = 0;
/*
    Flags3
    BIT         Estado          Descripcion
    0           0               No iniciar almacenamiento de paquete memoria externa
                1               Iniciar almacenamiento en memoria externa
    1           0               No se ha recibido paquete de PC (UCA1RXBUF)
                1               Se recibio paquete de UCA1RXBUF
    2           0               Memoria no llena
                1               Memoria externa llena
    3           0               No se habilita procesamiento principal cada segundo
                1               Procesamiento principal cada segundo habilitado
    4           0               
                1               
    5           0               getPacketCount no es tu turno
                1               getPacketCount es tu turno
    6           0               savePacketCount no ha terminado
                1               savePacketCount ha terminado
    7           0               No esta listo PacketCount para pasarlo a Package
                                Ya esta listo PacketCount para pasarlo a Package

*/

unsigned char Flags4 = 0;
/*
    BIT         Estado          Descripcion
    0           0               No esta lista la muestra de LPS331AP
                1               Ya esta lista la muestra de LPS331AP
    1           0               No se ha despertado a XBEE durante el presente ciclo
                1               Ya se desperto a XBEE durante el presente ciclo        
    2           0               No Ejecutar savePacketCount
                1               Ejecutar savePacketCount 
    3           0               No es turno de RTC_getMissionTime
                1               Es turno de RTC_getMissionTime
    4           0               No esta lista muestra de RTC_getMissionTime
                1               Esta lista muestra de RTC_getMissionTime


    6           0               No es Turno de iniciar Timer de SLEEP XBEE
                1               Turno de iniciar 
    7           0               No es turno de dormir XBEE
                1               Turno de dormir XBEE          

*/


unsigned char datosListosFlags = 0;
/*    
    datosListosFlags
    BIT         Estado          Descripcion
    0           0               Temperatura no lista en paquete de datos
                1               Temperatura lista en paquete de datos
    1           0               Voltaje NO listo en paquete de datos
                1               Voltaje listo en paquete de datos
    2           0               Temperatura no lista en paquete de datos**
                1               Temperatura Lista en paquete de datos**
    3           0               Presion no lista en paquete de datos
                1               Presion lista en paquete de datos
    4           0               Acceleracion  no lista en paquete de datos
                1               Aceleracion lista en paquete de datos
    5           0               Packet Count no lista en paquete de datos
                1               Packet Count listo en paquete de datos
    6           0               Mission Time no listo en paquete de datos
                1               Mission Time no listo en paquete de datos
*/

unsigned char procesoTerminadoFlags = 0;
/*

    procesoTerminadoFlags
    BIT         Estado          Descripcion
    0           0               No se ha terminado transmision I2C solicitada
                1               Transmision I2C solicitada terminada
    1           0               TIMER0_A2 CCR2 no ha terminado cuenta
                1               TIMER0_A2 CCR2 YA termino cuenta
    2           0               No ha terminado recepcion I2C
                1               Recepcion I2C terminada
    3           0               Envio XBEE TX no terminado
                1               Envio XBEE TX Terminado
    4           0               TIMER0_A3 CCR3 no ha terminado cuenta
                1               TIMER0_A3 CCR3 Ya termino cuenta
    5           0               TIMER0_A4 CCR4 no ha terminado cuenta
                1               TIMER0_A4 CCR4 YA termino cuenta
    6           0               TIMER0_A1 CCR1 no ha terminado cuenta
                1               TIMER0_A1 CCR1 YA termino cuenta
    7           0               Escritura de paquete en memoria externa no terminado
                1               Escritura de paquete en memooria terminado 

*/

unsigned char procesoTerminadoFlags2 = 0;

/*

    BIT       Estado            Descripcion
    0         0                 No ha terminado proceso de getNextWritableAddress
              1                 Ha terminado proces de getNextWritableAddress
    1         0                 No ha terminado proceso de updateNextWritableAddress
              1                 Ha terminado proceso de updateNextWritableAddress
    2         0                 TA1CCR1 no ha terminado
              1                 TA1CCR1 ha terminado
    3         0                 TA1CCR2 no ha terminado
              1                 TA1CCR2 ha terminado
    4         0                 TA2CCR1 no ha terminado
              1                 TA2CCR1 ha terminado
    5         0                 readPacketExternalEEPROM no ha terminado
              1                 readPacketExternalEEPROM ha terminado
*/

unsigned char procesoIniciadoFlags = 0;
/*
    
    procesoIniciadoFlags
    BIT         ESTADO          Descripcion
    0           0               Proceso de conversionADC no iniciado
                1               Proceoso ADC iniciado
    


*/


/*    ------ STATE VARIABLES ------ */

unsigned char flightState = 0;


/*    ------ MONITOR MODE FLAGS ------ */

char MFlags1 = 0;

/*

    MFlags1
    Bit          Estado          Descripcion
    0           0               No se ha recibido dato por PC_RX (UCA1RXBUF)                                 
                1               Se recibio dato por PC_RX (UC1RXBUF)
    1           0               Transmision por PC_TX no esta en curso
                1               Transmision por PC_TX esta en curso
*/


/*    ------ EXTERNAL MEMORY VARIABLES -----  */

unsigned int WRITE_ADDRESS = 0;         // Almacena la direccion a direccionar en memoria
                                        // externa para escritura 

unsigned int READ_ADDRESS = 0;          // Almacena la dirección en memoria externa para 
                                        // para leer

unsigned int ADDRESS_POINTER = 0;       // Apunta a una dirección en memoria externa

char EXTERNAL_MEMORY_BYTEWRITE_PROC = 0;    // Indicador de proximo paso de escritura en ejecucion
                                            // actualmente

char EXTERNAL_MEMORY_PACKETWRITE_PROC = 0;   // Indicador de proxima paso de escritura de paquete 

char EXTERNAL_MEMORY_BYTEREAD_PROC = 0;     // Indicador de proximo paso de lectura en ejecuación
                                        // actualmente
char EXTERNAL_MEMORY_PACKETREAD_PROC = 0;

char getNextWritableAddress_PROC = 0;   // Indicador de proximo paso de obtención de dirección
                                        // para almacenar datos

int NextWritableAddress = 0x003A;      

unsigned char EXTERNAL_MEMORY_TX_BUFFER[50] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                               0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

unsigned char updateNextWritableAddress_PROC = 0;

unsigned char guardarPaqueteCFSW_PROC = 0;



/*   ---- PC Monitor Mode Messages ----- */
unsigned char enterMonitorMode[10]={'M','O','N','I','T','O','R','E','O',0x0D};
unsigned char exitMonitorMode[6]={'A','D','I','O','S', 0x0D};


/*  ----- RTC Variables ----- */
unsigned char RTC_getMissionTime_PROC = 0;
unsigned char RTC_getMissionSeconds_PROC = 0;
unsigned char RTC_getMissionMinutes_PROC = 0;
unsigned char RTC_getMissionHours_PROC = 0;
unsigned char RTC_setMissionTime_PROC = 0;
unsigned int missionTimeSeconds = 0;



/*   --- Definicion de Prototipos --- */
void configureIOPorts(void);
void reduceXT1_XTAL_DriveStrength(void);
void configureClocks(void);
void configureREF(void);
void configureADC12A(void);
void selectADC12A_CHAN0(void);
void selectADC12A_CHAN10(void);
void startADC12A_Conversion(void);


void configureTimerA0(void);
void configureTimerA1(void);
void configureTimerA2(void);
void configureTimerB0(void);


void configureSystem(void);
void configureWDT(void);
void configureUSCI_A0(void);


void binaryToASCII(unsigned int binary,unsigned char *array);
void voltageBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset);


void startXBEETransmission(void);
void startXBEETransmission2(unsigned char *array, char longitud);

void startPCTransmission(unsigned char *array, char longitud);
void sampleADC(void);
void configureUSCI_B0(void);
void startMasterTransmitUSCI_B0(unsigned char slave_address, unsigned char *datos, unsigned char length);
void despertarXBEE(void);


void setTimerA0_CCR1(int tiempo);
void setTimerA0_CCR2(int tiempo);
void setTimerA0_CCR3(int tiempo);
void setTimerA0_CCR4(int tiempo);
void setTimerA1_CCR2(int tiempo);
void setTimerA2_CCR1(int tiempo);


void startMasterReceiveUSCI_B0(unsigned char slave_address, unsigned char number);
void sampleACCSensor(void);
void configureACCSensorProc(void);
void configureACCSensor(char data_format);

void bmp085CalWordBinaryToASCII_Signed(int binary, unsigned char *array, unsigned char offset);
void bmp085CalWordBinaryToASCII_Unsigned(unsigned int binary, unsigned char *array, unsigned char offset);
void getCalibrationDataBMP085_2(void);
void getCalibrationDataBMP085(void);
void getCalBMP085(void);
void getUT_BMP085(void);
void getUP_BMP085(void);


void configureUSCI_A1(void);
void configurePortMappingPins(void);
void tempSensorBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset);
void presSensorBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset);
void accSensorXBinaryToASCII(int binary, unsigned char *array, unsigned char offset);
void packetCountBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset);
void rtcBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset);


char startMasterReceiveUSCI_B0_OneByte(unsigned char slave_address);

/*
void flashByteWrite(unsigned int *address, char data);
void flashEraseSegment(unsigned int *address);
void flashWordWrite(unsigned int *address, unsigned int data);
void flashLongWordWrite(unsigned int *address, unsigned long data);
*/

void writeByteExternalEEPROM2(char memoryAddress, unsigned char *address_data);
void readByteExternalEEPROM2(char deviceAddress, unsigned char *address);

void writePacketExternalEEPROM_24XX(char memoryAddress, unsigned char *address_data, unsigned char length);
void readPacketExternalEEPROM(char deviceAddress, unsigned char *address, unsigned char length);

void eraseExternalMemoryComplete(void);
void eraseExternalMemory(int start_erase_address);
void readExternalMemoryComplete(void);
void readExternalMemory(int start_read_address);

void initExternalMemory(void);

void guardarPaqueteMemoriaExterna(void);
void getNextWritableAddressExternalMemory(void);
void saveDataToExternalMemory(int address, unsigned char *datos, unsigned char length);
void updateNextWritableAddress(void);
void updateNextWritableAddress2(int address);

void getPacketCount(void);
void savePacketCount(void);

void armarPaquetePFSW(unsigned char* array);

void getMissionTime(void);
void getMissionTimeSeconds(void);
void getMissionTimeMinutes(void);
void getMissionTimeHours(void);
void setMissionTime(void); 


__interrupt void TIMER0_A0_ISR(void);
__interrupt void ADC12A_ISR(void);
__interrupt void WDT_ISR(void);
__interrupt void USCI_A0_ISR(void);
__interrupt void USCI_B0_ISR(void);
__interrupt void TIMER0_A1_ISR(void);
__interrupt void USCI_A1_ISR(void);
__interrupt void TIMER1_A0_ISR(void);
__interrupt void TIMER1_A1_ISR(void);
//__interrupt void TIMER2_A0_ISR(void);
__interrupt void TIMER2_A1_ISR(void);
__interrupt void PORT1_ISR(void);


#pragma vector=WDT_VECTOR
__interrupt void WDT_ISR(void){
    /*
    //Blinkear LED
    //P1OUT ^= BIT0;
    // Apagar WDTIFG Flag
    SFRIFG1 &= ~(WDTIFG);  
    
    
    // Se va modificar ADC12CTL0, apagar ADC12ENC
    ADC12CTL0 &= ~(ADC12ENC);
    // Encender modulo ADC12A
    ADC12CTL0 |= ADC12ON;
    //Seleccionar Canal0
    selectADC12A_CHAN0();
    //Iniciar una conversion del ADC12A
    startADC12A_Conversion();    
    //LPM3_EXIT;
    
    
    // Comenzar transmision habilitando UCA0SWRST
    //Deshabilitar y Habilitar USCI_A0
    //UCA0CTL1 |= UCSWRST;
    UCA0CTL1 &= ~(UCSWRST);    
    // Habilitar interrupciones de TX y RX
    UCA0IE |= UCTXIE + UCRXIE;
    
    // Inicializar variables de transmision
    XBEE_TXBUF = PFSW_Package;
    XBEE_TXBUF_LENGTH = PFSW_Package_Length;
    // Incrementar la cuenta de paquetes
    XBEE_TXBUF_COUNTER++;
    
    
    // Habilitar conversion de sensores + transmision a XBEE
    //Flags1 |= (BIT2 + BIT1);
        
    // Salir de LPM
    //LPM1_EXIT;
    */
}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void){
    //Blinkear LED
    P1OUT |= BIT2;
  
    //Limpiar bandera de TIMER0 CCR0
    TA0CCR0 &= ~(CCIFG);
    
    // Habilitar conversion de sensores + transmision a XBEE
    Flags1 |= (BIT2 + BIT1);

    // Habilitar procesamiento principal cada segundo
    Flags3 |= BIT3;

    // Habilitar muestreo de primer sensor: ACC Sensor
    Flags2 |= BIT5;

    // Indicar que aun no se ha despertado a XBEE durante este ciclo
    Flags4 &= ~BIT1;    
        
    // Salir de LPM
    LPM1_EXIT;   
}

// Interrupt vector for TIMER0 CCR1-CCR5, TA0 Interrupts
#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void){
    switch(TA0IV)
    {
        case  0: break;                          // No interrupt
        case  2:                                 // CCR1IFG 
                
            //Tiempo de wake-up terminado, indicar que XBEE
            //esta disponible
            Flags1 |= BIT5;
            
            //Deshabilitar CCR1IFG hasta nueva orden
            TA0CCTL1 &= ~(CCIE);
            
            //Apagar LED de tiempo de espera wake-up
            //P2OUT &= ~(BIT7);

            // Indicar que este timer ya vencio
            procesoTerminadoFlags |= BIT6;
        
        
            //Esto necesita ser procesado.
            LowPowerFlags &= ~(BIT5);
            LPM1_EXIT;
            break;
        case  4:                                 // CCR2IFG 
            
            // Deshabilitar CCR2IFG hasta nueva orden
            TA0CCTL2 &= ~(CCIE);
            
            // Indicar que este timer ya vencio
            procesoTerminadoFlags |= BIT1;

            // Indicar que es turno de poner XBEE en SLEEP
            Flags4 |= BIT7;            
            
            //Esto necesita ser procesado
            LowPowerFlags &= ~(BIT4);
            LPM1_EXIT;
                       
            break;
        case  6:                                  // CCR3IFG

            // Deshabilitar CCR2IFG hasta nueva orden
            TA0CCTL3 &= ~(CCIE);
            
            // Indicar que este timer ya vencio
            procesoTerminadoFlags |= BIT4;
            
            //Esto necesita ser procesado
            LowPowerFlags &= ~(BIT6);
            LPM1_EXIT;

            break;
        case  8:                                 // CCR4IFG


            // Deshabilitar CCR2IFG hasta nueva orden
            TA0CCTL4 &= ~(CCIE);
            
            // Indicar que este timer ya vencio
            procesoTerminadoFlags |= BIT5;
            
            //Esto necesita ser procesado
            LowPowerFlags &= ~(BIT7);
            LPM1_EXIT;

            break;
        case 10: break;                          // reserved
        case 12: break;                          // reserved
        case 14:                                 // TA0IFG
            //P1OUT ^= 0x01;                  
            break;
        default: break; 
    }

}  

#pragma vector=ADC12_VECTOR
__interrupt void ADC12A_ISR(void){
  
    switch(ADC12IV){
        case  0: break;                           // Vector  0:  No interrupt
        case  2: break;                           // Vector  2:  ADC overflow
        case  4: break;                           // Vector  4:  ADC timing overflow
        case  6:                                  // Vector  6:  ADC12IFG0
            // Leer conversion, debería apagar FLAG0
            VOLTAJE_ADC = ADC12MEM0;                      
            // Apagar la FLAG0 de todos modos
            ADC12IFG &= ~(ADC12IFG0);
            //Seleccionar Canal 10 (Sensor de Temperatura)
            //selectADC12A_CHAN10();
            //Iniciar conversion ADC12A
            //startADC12A_Conversion();
            
            //Indicar que ya se puede convertir a ASCII
            Flags2 |= BIT0;
            
            //Evitar que se vuelva a entrar a modo LPM inmediatamente
            //despues de salir de esta interrupcion ya que es necesario
            //el procesamiento de otros datos
            LowPowerFlags &= ~(BIT0);
            
            //Salir de LPM
            LPM1_EXIT;
            
            break;                           
        
        case  8: break;                           // Vector  8:  ADC12IFG1
        case 10: break;                           // Vector 10:  ADC12IFG2
        case 12: break;                           // Vector 12:  ADC12IFG3
        case 14: break;                           // Vector 14:  ADC12IFG4
        case 16: break;                           // Vector 16:  ADC12IFG5
        case 18: break;                           // Vector 18:  ADC12IFG6
        case 20: break;                           // Vector 20:  ADC12IFG7
        case 22: break;                           // Vector 22:  ADC12IFG8
        case 24: break;                           // Vector 24:  ADC12IFG9
        case 26:                                  // Vector 26:  ADC12IFG10
            // Leer conversion, deberia pagar FLAG10
            ADC12MEM10 = ADC12MEM10;
            // Apagar FLAG10 de todos modos
            ADC12IFG &= ~(ADC12IFG10);
            // Deshabilitar conversiones y habilitar edicion de ADC12CTL0
            ADC12CTL0 &= ~(ADC12ENC);
            // Apagar ADC, ahorrar energia
            ADC12CTL0 &= ~(ADC12ON);
            
            break;
            
        case 28: break;                           // Vector 28:  ADC12IFG11
        case 30: break;                           // Vector 30:  ADC12IFG12
        case 32: break;                           // Vector 32:  ADC12IFG13
        case 34: break;                           // Vector 34:  ADC12IFG14
        default: break; 
    } 
}

#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void){
    
    switch(UCA0IV){
        case 0:break;                             // Vector 0 - no interrupt
        case 2:                                   // Vector 2 - RXIFG
            // Borrar bandera
            UCA0IFG &= ~(UCRXIFG);
            //Almacenar dato
            XBEE_RXBUF[XBEE_RXBUF_POINTER] = UCA0RXBUF;
            //Incrementar BUFFER
            XBEE_RXBUF_POINTER++;
            
            if( XBEE_RXBUF_POINTER == 64){
                // Se lleno buffer, comenzar a llenarlo desde
                // el inicio
                XBEE_RXBUF_POINTER = 0;
            }
            
            //Indicar que se debe procesar dato recibido
            Flags1 |= BIT0;
            
            //Deshabilitar entrada a modo LowPower
            //LowPowerFlags &= ~(BIT0);
            //Salir de modo LowPower despues de esta ISR
            
            
            
            LPM1_EXIT;
            
            break;
        case 4:                                   // Vector 4 - TXIFG
            
            if( XBEE_TXBUF_POINTER < XBEE_TXBUF_LENGTH){
                UCA0IFG &= ~(UCTXIFG);
                UCA0TXBUF = XBEE_TXBUF[XBEE_TXBUF_POINTER]; 
                XBEE_TXBUF_POINTER++;
            }
            else{
                /*
                // Envio terminado, deshabilitar transmision
                P4OUT ^= BIT2;
                i = 0;
                //UCA0CTL1 |= UCSWRST;
                UCA0IE &= ~(UCTXIE + UCRXIE);
                //Habilitar FLAG por que ya no se 
                UCA0IFG |= UCTXIFG;
                */
                //Verificar que no haya transmision activa,
                // antes de deshabilitar el modulo
                if( ! (UCA0STAT & UCBUSY)){
                  
                    // Solicitar modo sleep a XBEE
                    //P3OUT |= (BIT2);

                    // Indicar que es turno de XBEE SLEEP TIMERA0_CCR2
                    Flags4 |= BIT6;
                    
                    // Indicar que XBEE ya no esta disponible
                    Flags1 &= ~(BIT5);
                    
                    //Resetear puntero
                    XBEE_TXBUF_POINTER = 0;
                    // deshabilitar modulo
                    //UCA0CTL1 |= UCSWRST;
                    
                    //Deshabilitar interrupcion de TX
                     UCA0IE &= ~(UCTXIE);
                     
                    // Indicar que ya no hay transmision en curso
                    Flags1 &= ~(BIT4);   
                    
                    // Habilitar almacenamiento en memoria externa
                    // como siguiente paso
                    Flags3 |= BIT0;
                    
                    //Indicar que este proceso ha terminado
                    procesoTerminadoFlags |= BIT3;
                    
                    // Transmision termino, requiere procesamiento posterior
                    LPM1_EXIT;
                    LowPowerFlags |= BIT2;
                    
                }
                // Setear flag ya que no se realizo transmision
                // y no se reactiva a menos que se haga una transmision
                //dentro de la ISR. SE DEBE HACER INCONDICIONALMENTE
                // SI NO SE REALIZA TRANSMISION
                UCA0IFG |= UCTXIFG;
                
            } 
            break;
        default: break;
    }
  
}

// Interrupt vectyor for TIMER1 CCR0 Register
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void){
    
}

// Interrupt vector for TIMER1 CCR1-CCR5 registers
#pragma vector = TIMER1_A1_VECTOR
__interrupt void TIMER1_A1_ISR(void){

    switch(TA1IV)
    {
        case  0: break;                          // No interrupt
        case  2:                                 // CCR1IFG 

            //Deshabilitar CCR1IFG hasta nueva orden
            //TA1CCTL1 &= ~(CCIE);
          
            // Proxima interrupcion en 83ms
            TA1CCR1 += 679;

            // Indicar que termino TA1CCR1
            procesoTerminadoFlags2 |= BIT2;
            
            if( TA1CCR1 > 8151){
              TA1CCR1 = 679;
            }
            /*
            do{
              samplePressure2();
            }while(LPS331AP_PROCESS_STATE != 0);
            
            // Indicar que ya se muestrearon sensores 
            // Esto lo debe indicar siempre el ultimo sensor
            //Flags1 &= ~(BIT2);

            // Revertir la indicacion hecha en samplePressure2
            Flags2 &= ~BIT3;
            
            */
            //updateFlightDirection();
        
            //Esto necesita ser procesado.
            //LowPowerFlags2 &= ~(BIT0);
            LPM1_EXIT;
            break;
        case  4:                                 // CCR2IFG 
          
            TA1CCTL2 &= ~(CCIE);
            
            // Indicar que este CCR2 Timer ya termino
            procesoTerminadoFlags2 |= BIT3;
            
            //Esto necesita ser procesado.
            LowPowerFlags2 &= ~(BIT1);
            LPM1_EXIT;
            

            break;
        case  6:                                  // CCR3IFG

            break;
        case  8:                                 // CCR4IFG

            break;
        case 10: break;                          // reserved
        case 12: break;                          // reserved
        case 14:                                 // TA0IFG
              
            break;
        default: break; 
    }

}

#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(){
    switch(UCB0IV){
        case  0: break;                           // Vector  0: No interrupts
        case  2: break;                           // Vector  2: ALIFG
        case  4:                                 // Vector  4: NACKIFG
            //Enviar STOP Condicition              
            UCB0CTL1 |= (UCTXSTP);
            
            procesoTerminadoFlags |= BIT0;
            break;
        case  6: break;                           // Vector  6: STTIFG
        case  8: break;                           // Vector  8: STPIFG
        case 10:                                  // Vector 10: RXIFG
            SENSOR_RXBUF_POINTER++;
            if(SENSOR_RXBUF_POINTER < (SENSOR_RX_EXPECTED -1)){
                
                //Leer dato recibido
                SENSOR_RXBUF[SENSOR_RXBUF_POINTER-1] = UCB0RXBUF;
                
                
                
            }
            else if( SENSOR_RXBUF_POINTER == (SENSOR_RX_EXPECTED -1)){
                //Enviar STOP Condicition              
                UCB0CTL1 |= (UCTXSTP);
              
                //Leer ultimo byte              
                SENSOR_RXBUF[SENSOR_RXBUF_POINTER-1] = UCB0RXBUF;
                
            }else{              
              

                //Leer ultimo byte              
                SENSOR_RXBUF[SENSOR_RXBUF_POINTER-1] = UCB0RXBUF;
              
                //Deshabilitar modulo
                UCB0IE &= ~(UCRXIE);
                
                //Resetear contador
                SENSOR_RXBUF_POINTER = 0;
                
                // Indicar que termino recepcion I2C
                procesoTerminadoFlags |= (BIT2);
                
                //Termino envio, procesamiento necesario
                LowPowerFlags &= ~(BIT3);
                LPM1_EXIT;
              
                
            }
            break;
          
        case 12:                                  // Vector 12: TXIFG  
          
            //Borrar bandera de transmision
            UCB0IFG &= ~(UCTXIFG);
            
            if(SENSOR_TXBUF_POINTER < SENSOR_TXBUF_LENGTH){
          
                //P4OUT |= BIT1;
                
                //Cargar dato
                UCB0TXBUF = SENSOR_TXBUF[SENSOR_TXBUF_POINTER];
                
                //Incrementar dato a enviar
                SENSOR_TXBUF_POINTER++;
                
                //P4OUT &= ~(BIT1);
                
            }else{
              
                //Transmision debe terminar
                UCB0CTL1 |= UCTXSTP;
              
                //Deshabilitar transmision
                UCB0IE &= ~(UCTXIE);
                
                //Rehabilitar TX Interrupt flag para proxima operacion
                UCB0IFG |= UCTXIFG;
                
                //Resetear puntero de datos
                SENSOR_TXBUF_POINTER = 0;  
                
                //Indicar que el proceso de transmision I2C ha terminado
                procesoTerminadoFlags |= BIT0;
                
                //Termino envio, procesamiento necesario
                LowPowerFlags &= ~(BIT1);
                LPM1_EXIT;
              
            }  
          
        break;
        default: break;
    }
}

/*
    TODO: Corregir bandera  (Flags1 |= BIT0) para indicar dato recibido
    TODO: Corregir bandera  de LowPowerFlags para RX y TX
    TODO: Corregir bandera de procesoTerminadoFlags para que se PC_TX

*/

#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(){
    
    switch(UCA1IV){
        case 0:break;                             // Vector 0 - no interrupt
        case 2:                                   // Vector 2 - RXIFG
            // Borrar bandera
            UCA1IFG &= ~(UCRXIFG);
            //Almacenar dato
            PC_RXBUF[PC_RXBUF_POINTER] = UCA1RXBUF;
            //Incrementar BUFFER
            PC_RXBUF_POINTER++;
            
            if( PC_RXBUF_POINTER == 64){
                // Se lleno buffer, comenzar a llenarlo desde
                // el inicio
                PC_RXBUF_POINTER = 0;
            }
            
            //Indicar que se debe procesar dato recibido
            // segun modo actual 
            if(modo==0xAA){
                // Modo monitoreo
                MFlags1 |= BIT0;
            
            }else{
                // Modo de vuelo
                Flags3 |= BIT1;
                LPM1_EXIT;
            }
           
            break;
        case 4:                                   // Vector 4 - TXIFG
            
            if( PC_TXBUF_POINTER < PC_TXBUF_LENGTH){

                // Apagar bandera
                UCA1IFG &= ~(UCTXIFG);

                // Cargar siguiente dato a transmitir
                UCA1TXBUF = PC_TXBUF[PC_TXBUF_POINTER];

                // Pasar a siguiente dato 
                PC_TXBUF_POINTER++;
            }
            else{
                /*
                // Envio terminado, deshabilitar transmision
                P4OUT ^= BIT2;
                i = 0;
                //UCA0CTL1 |= UCSWRST;
                UCA0IE &= ~(UCTXIE + UCRXIE);
                //Habilitar FLAG por que ya no se 
                UCA0IFG |= UCTXIFG;
                */
                //Verificar que no haya transmision activa,
                // antes de deshabilitar el modulo
                if( ! (UCA1STAT & UCBUSY)){

                    
                    //Resetear puntero
                    PC_TXBUF_POINTER = 0;
                    
                    //Deshabilitar interrupcion de TX
                     UCA1IE &= ~(UCTXIE);
                     
                    // Indicar que ya no hay transmision en curso
                    MFlags1 &= ~(BIT1);   
                    
                    //Indicar que este proceso ha terminado (revisar la necesidad de esta bandera)
                    //procesoTerminadoFlags |= BIT3;
                    
                    
                }
                // Setear flag ya que no se realizo transmision
                // y no se reactiva a menos que se haga una transmision
                //dentro de la ISR. SE DEBE HACER INCONDICIONALMENTE
                // SI NO SE REALIZA TRANSMISION
                UCA1IFG |= UCTXIFG;
                
            } 
            break;
        default: break;
    }


}


#pragma vector = TIMER2_A1_VECTOR
__interrupt void TIMER2_A1_ISR(void){

    switch(TA2IV)
    {
        //case  0: break;                          // No interrupt
        case  2:                                 // CCR1IFG 

            //Deshabilitar CCR1IFG hasta nueva orden
            TA2CCTL1 &= ~(CCIE);
          
            // Indicar que este timer ya termino
            procesoTerminadoFlags2 |= BIT4;
        
            //Esto necesita ser procesado.
            LowPowerFlags2 &= ~(BIT2);

            // Salir de modo sleep
            LPM1_EXIT;
            break;
        default: break; 
    }
}


#pragma vector = PORT1_VECTOR
__interrupt void PORT1_ISR(void){

    switch(P1IV){

        case 0:
            break;
        case 2:   // P1.0
            break;
        case 4:   // P1.1
            break;
        case 6:   // P1.2        
            break;
        case 8:   // P1.3
            break;
        case 10:  // P1.4  
            break;
        case 12:  // P1.5

              //Blinkear LED
              P1OUT |= BIT2;

              //Limpiar bandera de TIMER0 CCR0
              TA0CCR0 &= ~(CCIFG);
              
              // Habilitar conversion de sensores + transmision a XBEE
              Flags1 |= (BIT2 + BIT1);

              // Habilitar procesamiento principal cada segundo
              Flags3 |= BIT3;

              // Habilitar muestreo de primer sensor: ACC Sensor
              Flags2 |= BIT5;

              // Indicar que aun no se ha despertado a XBEE durante este ciclo
              Flags4 &= ~BIT1;    
                  
              // Salir de LPM
              LPM1_EXIT;   

            break;
        case 14:  // P1.6
            break;  
        case 16:  // P1.7
            break;
        default:
            break;



    }
}  





void startMasterTransmitUSCI_B0(unsigned char slave_address, unsigned char *datos, unsigned char length){
  
    //Cargar datos a transmitir
    SENSOR_TXBUF = datos;
    SENSOR_TXBUF_LENGTH = length;
    
    //Indicar que el proceso de transmision no ha terminado (apenas comienza)
    procesoTerminadoFlags &= ~(BIT0);
  
  
    //Cargar direccion de Esclavo
    UCB0I2CSA = slave_address;
    
    //Seleccionar modo Transmit
    UCB0CTL1 |= UCTR;
    
    //Generar condicion start
    UCB0CTL1 |= UCTXSTT;
    
    //Habilitar interrupciones
    UCB0IE |= UCNACKIE + UCTXIE;  
}

void configurePortMappingPins(void){

    // Write port mapping write access key
    PMAPKEYID = PMAPKEY;
    // Verificar que acceso haya sido concedido
    if( !(PMAPCTL & PMAPLOCKED ) ){
        
        // Configurar P4.4 como UCA1RXD
        P4MAP4 = PM_UCA1TXD;
        // Configurar P4.5 como UCA1TXD
        P4MAP5 = PM_UCA1RXD;
    }else{
    }
}

void configureUSCI_A1(void){

    // Para modificar todos los registros UCSWRST = 1
    UCA1CTL1 |= UCSWRST;
  
    // No paridad, LSB primero, 8 bit data, 1 stop bit, Modo UART,
    // Comms asincrono, 
    UCA1CTL0 |= 0;
  
    // BRCKL = SMCLK = DCO, Reject Erroneous characters, BRK Characters no RXIFG,
    // No dormant
    UCA1CTL1 |= UCSSEL_2;
  
    // Baudrate prescaler registers for 57600 baud/sec
    UCA1BR0 |= 109;
    UCA1BR1 |= 0;
  
    // Low Frequency Mode (No oversampling), UCBRS = 1, UCBRF = 0  
    // First Stage and Second Stage modulation for 57600 bps
    UCA1MCTL |= UCBRF_0 + UCBRS_2;  
       
    // Para modificar todos los registros UCSWRST = 1
    UCA1CTL1 &= ~(UCSWRST);
    
    // Habilitar interrupcion de recepcion
    UCA1IE |=UCRXIE;
}

void configureUSCI_B0(){

    // Mantener USCI_B0 en reset para configuracion
    UCB0CTL1 |= UCSWRST;        
  
    // 7 bit addresing (self & slave), NO multi-master, Work as MASTER,
    // I2C Mode, Synchronous
    UCB0CTL0 |= UCMST + UCMODE_3 + UCSYNC; 
    
    // BRCLK = SMCLK = DCO
    UCB0CTL1 |= UCSSEL__SMCLK;
    
    // Para bitclk de 100kbps @DC0=2.02MHz, UCBR0 = 2.02M/100k= 20.2
    // , entonces: UCB0BR0 = 20, UCB0BR1 = 0;
    UCB0BR0 = 20;
    UCB0BR1 = 0;
    
    // Do not respond to general call, NO own addres configured
    UCB0I2COA &= ~(UCGCEN);
    
    // Habilitar USCI_B0
    UCB0CTL1 &= ~(UCSWRST);   
}

// For UART, 57600, 8Bit, No parity, 1 StopBit
void configureUSCI_A0(void){
    
    // Para modificar todos los registros UCSWRST = 1
    UCA0CTL1 |= UCSWRST;
  
    // No paridad, LSB primero, 8 bit data, 1 stop bit, Modo UART,
    // Comms asincrono, 
    UCA0CTL0 |= 0;
  
    // BRCKL = SMCLK = DCO, Reject Erroneous characters, BRK Characters no RXIFG,
    // No dormant
    UCA0CTL1 |= UCSSEL_2;
  
    // Baudrate prescaler registers for 57600 baud/sec
    UCA0BR0 |= 109;
    UCA0BR1 |= 0;
  
    // Low Frequency Mode (No oversampling), UCBRS = 1, UCBRF = 0  
    // First Stage and Second Stage modulation for 57600 bps
    UCA0MCTL |= UCBRF_0 + UCBRS_2;
    
    // Para modificar todos los registros UCSWRST = 1
    UCA0CTL1 &= ~(UCSWRST);
    
    // Habilitar interrupcion de transmision
    UCA0IE |= UCRXIE;

}

void configureWDT(void){

    //WDTCLK = VLOCLK/(2^13), Reset WDTCounter, Timer Mode
    WDTCTL = WDTPW + WDTSSEL_2 + WDTCNTCL + WDTIS_4 +WDTTMSEL;    
    //Enable WDT Timer Interrupt
    //SFRIE1 |= WDTIE;
    
}

void configureSystem(){
    
    _BIS_SR(GIE);

}


/*
    IO Pins Configuration (alternative)
    P1.0 = ACLK Output
    P1.1 = 1s indicator (ACLK Output)
    P1.2 = 
    P1.3 = 
    
    P3.0 = SENSORS I2C SDA
    P3.1 = SENSORS I2C SCL

    P3.2 = XBEE Sleep/WakeUp Output (SLEEP_RQ)
    P3.3 = XBEE_TX UART (USCI_A0 TX)
    P3.4 = XBEE_RX UART (USCI_A0 RX)


    P2.5 = Sleep Enter/Exit Indicator
    P2.7 = XBEE Wake Up Timer Output
    

    P4.1 = XBEE_TX One Byte Transmited Indicator
    P4.7 = XBEE_RX One Byte Received Indicator

*/


void configureIOPorts(){

  
    /*   ---- PORT1 CONFIGURATION ---- */
    //Configurar P1.1,P1.2,P1.3 como salida
    //Configurar P1.0 como ACLK output
    // P1.5 como entrada de RTC para interrupt 1s
    P1DIR = 0;
    P1DIR = (BIT6 + BIT4 + BIT3 + BIT2 + BIT1 + BIT0);
    P1OUT = 0;
    P1SEL |= BIT0;

    // P1.5 Interrupt Configuration
    P1IES &= ~BIT5;   // Interrupt on low to high transition
    P1IE = BIT5;      // Enable P1.5 interrupt
    P1IFG &= ~BIT5;   // Borrar bandera por si se habilito sola
    P1REN &= ~BIT5;   // Deshabilitar pull-up/down resistor

    
    /*   ---- PORT2 CONFIGURATION ---- */
    // Configurar P2.2 como SMCLK output
    // P2.7 output
    P2DIR = 0;
    P2DIR |= (BIT7 +BIT5+ BIT2);
    P2OUT = 0;
    P2SEL |= BIT2;
    
    /*   ---- PORT3 CONFIGURATION ---- */
    // P3.4, P3.3, P3.2, P3.5, P3.6 como salidas
    //P3.3 = UCA0TXD, P3.4 = UCA0RXD
    // P3.0 = 0 (input) SDA for USCI_B0, P3.1 = 0 (input) SCL for USCI_B0
    // to allow for I2C operation with internal pullups
    P3DIR = 0;
    P3DIR |= (BIT6 + BIT5 + BIT4 + BIT3 + BIT2);
    P3REN |= BIT1 + BIT0;       //
    P3OUT |= BIT1 + BIT0;       // Enable pull up resistors for P3.0,P3.1
    P3SEL |= BIT3 + BIT4 + BIT1 + BIT0;
    
    /*   ---- PORT4 CONFIGURATION ---- */    
    // P4.7 salida, LED2 en Launchpad, funcion I/O
    // P4.2, P4.1, P4.0 como salidas
    // P4.4 = UCA1TXD, P4.5 = UC1RXD
    P4DIR = 0;
    P4DIR = (BIT7 + BIT2 + BIT1 + BIT0);
    P4OUT = 0;
    P4SEL = (BIT4 + BIT5);

    /*   ---- PORT5 CONFIGURATION ---- */    
    //Configurar P5.4,P5.5 NO funcionan como X1IN y X1OUT, respectivamente
    //P5.0 como salida VREF+
    P5DIR = 0;
    P5DIR |= 0;
    P5SEL |= (BIT0);
    P5OUT = 0;


    
    /*   ---- PORT6 CONFIGURATION ---- */
    // P6.0 as A0 Analog Input, Disable Comparator Input channel CB0 on that pin
    // P6.6, P6.5 as output
    P6DIR = 0;          //Reset
    P6DIR = (BIT6 + BIT5);
    P6SEL |= BIT0;
    P6OUT &= ~(BIT0);
    CBCTL3 |= CBPD0;   
    
    /*   ---- PORT7 CONFIGURATION ---- */
    //P7.7 as MCLK output, P7.7 as output
    P7DIR = 0;
    P7DIR |= BIT7 + BIT0;
    P7OUT = 0;
    P7SEL |= BIT7;
    
    /*   ---- PORT8 CONFIGURATION --- */
    // P8.1 como salida
    P8DIR = 0;
    P8DIR = BIT1;
    P8OUT = 0;
}

void reduceXT1_XTAL_DriveStrength(){
    
    //Reduce XTAL on XT1 drive Strength after it is stable
    //Consume less current for XTAL
    UCSCTL6 &= ~(XT1DRIVE_3);   
}

void configureClocks(){
  
    // Select REFOCLK for FLL
    UCSCTL3 = SELREF__REFOCLK;
  
    // MCLOCK = DCO
    // SMCLOCK = DCO
    // ACLOCK = VLO
    UCSCTL4 = SELA__VLOCLK + SELS__DCOCLK + SELM__DCOCLK;
    
    //ACLK = ACLK/1, SMCLK = SMCLK/2, MCLK = MCLK/1
    UCSCTL5 = DIVPA__1 + DIVS__2 + DIVM__1;
    
    //Configuracion XT1CLK para 32.748kHz Crystal
    //Highest Drive Strength, LFmode, Sourced Internally(NoBypass), 
    //12pF Internal Load Capacitance
    //UCSCTL6 &= ~(XT1OFF);
    //UCSCTL6 |= XT1DRIVE_3 + XCAP_3;

}

void configureREF(){
    // REF module has control of REF voltages, VREF = 2.5V, REF voltage
    // available externally, REF module ON, Enable Temp Sensor
    REFCTL0 |= REFMSTR + REFVSEL_2 + REFOUT + REFON;

}

void configureADC12A(){
  
    // Configure ADC    
    // Encender ADC12A, Sample_time = 8 ciclos de ADC12CLK for CHAN0,
    // 96 ADC12CLK for CHAN10 (TempSensor t_sample >= 30us), SHI trigger single
    ADC12CTL0 |= ADC12ON + ADC12SHT00 + ADC12SHT10 + ADC12SHT12;
    // ADC12CLK = ADC12CLK/3, ADC12CLK = ADC12OSC(MODOSC),Single channel & 
    // conversion, Make conversion on ADC12MEM0, Sample&Hold = ADC12SC bit,
    // SAMPCON from timer (extended mode)
    ADC12CTL1 |= ADC12SHS_0 + ADC12CSTARTADD_0 + ADC12DIV_2 + ADC12SSEL_0 + ADC12CONSEQ_0 + ADC12SHP;
    // 12 bit resolution, Sampling rate < 50 ksps, output REF, REF in burst mode
    // available only when ADC12 is sampling.
    ADC12CTL2 |= ADC12RES_2 + ADC12SR + ADC12REFOUT + ADC12REFBURST;
    
    //Configuracion de Registros de almacenamiento 
    
    // MEM0:  Vref+ =VREF+ & Vref- = VREF-, Channel 0 (P6.0) 
    ADC12MCTL0 |= ADC12SREF_3 + ADC12INCH_0;
    
    // MEM0:  Vref+ =VREF+ & Vref- = VREF-, Channel 10 (Temp Sensor) 
    ADC12MCTL10 |= ADC12SREF_3 + ADC12INCH_10;
    
    // Habilitar interrupciones de CHAN0 y CHAN10 (Temp)
    ADC12IE = ADC12IE0 + ADC12IE10;
    
    
}

void selectADC12A_CHAN0(){
    
    // Disable conversion to modify ADC12A Control Registers 1 & 0
    ADC12CTL0 &= ~(ADC12ENC);
    
    // Select CHAN0 for single channel single conversion
    ADC12CTL1 &= ~( ADC12CSTARTADD0 + ADC12CSTARTADD1 + ADC12CSTARTADD2 + ADC12CSTARTADD3);
    ADC12CTL1 |= ADC12CSTARTADD_0;
    
}

/*  Select CHANNEL 10 for ADC12A. This is Internal Temperature Sensor  */
void selectADC12A_CHAN10(){
    
    // Disable conversion to modify ADC12A Control Registers 1 & 0
    ADC12CTL0 &= ~(ADC12ENC);
    // Select CHAN0 for single channel single conversion
    ADC12CTL1 &= ~( ADC12CSTARTADD0 + ADC12CSTARTADD1 + ADC12CSTARTADD2 + ADC12CSTARTADD3);
    ADC12CTL1 |= ADC12CSTARTADD_10;

}

void startADC12A_Conversion(){      
    // Enable ADC12CTL0 and command Start
    ADC12CTL0 |= ADC12ENC + ADC12SC;
}

void sampleADC(){
  
    //Indicar que se ha iniciado el proceso
    procesoIniciadoFlags |= BIT0;    
    // Se va modificar ADC12CTL0, apagar ADC12ENC
    ADC12CTL0 &= ~(ADC12ENC);
    // Encender modulo ADC12A
    ADC12CTL0 |= ADC12ON;
    // Seleccionar Canal0
    selectADC12A_CHAN0();
    // Iniciar una conversion del ADC12A
    startADC12A_Conversion();
    

}

void configureTimerA0(){
    
    // TACLK Source = ACLK/1, Up mode,
    // Clear TA0R to reset all clocks
    TA0EX0 = TAIDEX_0;
    TA0CTL = TASSEL_1 +  ID_0 + MC__UP + TACLR;
    
    // Enable CCIE Interrupt, Compare mode (No Capture),
    // on CCR0
    //TA0CCTL0 = CCIE;
    
    // Enable CCR1 on TA0, Compare mode
    //TA0CCTL1 = CCIE;   //Will be enabled when necessary
    
    // Set compare register to 9140 (ACLK = VLOCLK = 9140Hz)
    TA0CCR0 = 9140;
    
}

void configureTimerA1(){
    
    // Divide CLK input by 1
    TA1EX0 = TAIDEX_0;
  
    // CLK Source = ACLK, CLK/1, Up mode, 
    TA1CTL = TASSEL_1 + ID_0 + MC__UP + TACLR;
    
    // Habilitar interrupcion TA1CCR1
    //TA1CCTL1 = CCIE;    
    
    // Periodo 1s ( TA1 CLK = ACLK = VLOCK = 8151 Hz)
    TA1CCR0 = 8151;    
    
    // Periodo de 83ms
    //TA1CCR1 = 679;

}

void configureTimerA2(){
    
    // Divide CLK input by 1
    TA2EX0 = TAIDEX_0;
  
    // CLK Source = ACLK, CLK/1, Up mode, 
    TA2CTL = TASSEL_1 + ID_0 + MC__UP + TACLR;
    
    // Habilitar interrupcion TA1CCR1
    //TA2CCTL2 = CCIE;    
    
    // Periodo 1s ( TA1 CLK = ACLK = VLOCK = 8151 Hz)
    TA2CCR0 = 8151;    
    
}

void configureTimerB0(){
        
    // Divide CLK input by 1
    TB0EX0 = TBIDEX_0;
  
    // CLK Source = ACLK, CLK/1, Up mode, 
    TB0CTL = TBSSEL_1 + ID_0 + MC__UP + TBCLR;
    
    //TA0CCR0 Compare mode, 
    //TB0CCTL1 = OUTMOD_6;    
    //TB0CCTL2 = OUTMOD_6;
    TB0CCTL3 = OUTMOD_6;
    
    // Periodo ~ 20ms ( TB0 CLK = ACLK = VLOCK =  8151Hz)
    TB0CCR0 = 163;
    
    // Ancho de pulso ~1ms    
    TB0CCR3 = 8;

}

/*
    Convierte un numero binario < 9999  a su equivalente en
    ASCII. Guarda los 4 caracteres ASCII generados a partir de la posicion
    de memoria indicada por array.
*/


void voltageBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset){
    
    unsigned int  a = binary;
    unsigned char index; 
    
    for( index = 2 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30; 
    
    
}

void startXBEETransmission(){
    
    // Inicializar variables de transmision
    XBEE_TXBUF = PFSW_TransPackage;
    XBEE_TXBUF_LENGTH = PFSW_TransPackage_Length;

    
    //Indicar que este proceso ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT3);   
    
    // Comenzar transmision habilitando UCA0SWRST
    //Deshabilitar y Habilitar USCI_A0
    //UCA0CTL1 |= UCSWRST;    
    // Habilitar interrupcion de TX
    UCA0IE |= UCTXIE;
    
    
    // Indicar que ya se inicio transmision, requerir una nueva iniciacion
    Flags1 &=  ~(BIT1);
    
    //  Indicar que transmision esta en curso
    Flags1 |= BIT4;

}

void startXBEETransmission2(unsigned char *array, char longitud){

    // Inicializar variables de transmision
    XBEE_TXBUF = array;
    XBEE_TXBUF_LENGTH = longitud;

    
    //Indicar que este proceso ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT3);   
    
    // Comenzar transmision habilitando UCA0SWRST
    //Deshabilitar y Habilitar USCI_A0
    //UCA0CTL1 |= UCSWRST;    
    // Habilitar interrupcion de TX
    UCA0IE |= UCTXIE;
    
    
    // Indicar que ya se inicio transmision, requerir una nueva iniciacion
    Flags1 &=  ~(BIT1);
    
    //  Indicar que transmision esta en curso
    Flags1 |= BIT4;    


}

void despertarXBEE(){
        
    //  Despertar a XBEE utilizando SLEEP_RQ
    P3OUT &= ~(BIT2);
    
    //LED de tiempo de espera
    //P2OUT |= BIT7;

    //Indicar que ya desperto XBEE
    Flags4 |=  BIT1;
    
   // Delay de 3ms para XBEE Wake Up
    setTimerA0_CCR1(165);      

    
  
}

void tempSensorBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset){

    unsigned int  a = binary;
    unsigned char index; 
    
    for( index = 3 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30; 


}

void presSensorBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset){

    unsigned int  a = binary;
    unsigned char index; 
    
    for( index = 3 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30; 

}

void accSensorXBinaryToASCII(int binary, unsigned char *array, unsigned char offset){
    
    unsigned int  a = binary;
    unsigned char index; 
    
    if( binary < 0){
        // Colocar signo negativo antes del numero
        *(array + offset - 1) = 0x2D;
        // Convertirlo a positivo
        a = ~(a)+1;
    }else{
        *(array + offset - 1) = 0x2B;        
    }
    
    for( index = 2 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30; 
  
}

void bmp085CalWordBinaryToASCII_Signed(int binary, unsigned char *array, unsigned char offset){
    
    int  a = binary;
    unsigned char index; 
    unsigned int b = 0;
    
    if( binary < 0){
        // Colocar signo negativo antes del numero
        *(array + offset - 1) = 0x2D;
        // Convertirlo a positivo
        //a = ~(a)+1;
        a = a * -1;
    }else{
        *(array + offset - 1) = 0x2B;        
    }
    
    if(a == -32768){
        b = 32768;
    }else{
      b = a;
    }

    for( index = 3 ; index > 0; index--){
        *(array + 1 + index + offset) = (b%10) + 0x30;  //Obtener residuo y convertir a ASCII
        b = b/10;    
    }
    
    *(array + 1 + offset) = (b%10) + 0x30;
    *(array + offset) = b/10 + 0x30; 
  
}

void bmp085CalWordBinaryToASCII_Unsigned(unsigned int binary, unsigned char *array, unsigned char offset){
    
    unsigned int  a = binary;
    unsigned char index; 
   
    *(array + offset - 1) = 0x2B;        
    
    for( index = 3 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30; 
  
}




void packetCountBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset){
            
    unsigned int  a = binary;
    unsigned char index; 
    
    for( index = 2 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30; 
  
  
}

void rtcBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset){

    unsigned int  a = binary;
    unsigned char index; 
    
    for( index = 2 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30;   

}

void setTimerA0_CCR1(int tiempo){
    
    //Stop TIMER0 para leer el valor de TA0R
    TA0CTL &= ~(MC__UP);
    
    // Comenzar espera para que XBEE salga de sleep: 3ms
    TA0CCR1 = TA0R + tiempo;
    
    if(TA0CCR1 > TA0CCR0){
        TA0CCR1 = tiempo;
    }
    
    //Reanudar TIMER0
    TA0CTL |= MC__UP;
    
    //Apagar flag de CCR1 por si se encendio anteriormente
    TA0CCTL1 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT6);
    
    // Habilitar interrupcion
    TA0CCTL1 |= CCIE;
    
}

void setTimerA0_CCR2(int tiempo){
    
    //Inicializar TIMER de espera especificado por sensor
                
    //Stop TIMER0 para leer el valor de TA0R
    TA0CTL &= ~(MC__UP);

    // Comenzar tiempo de espera especificado
    TA0CCR2 = TA0R + tiempo;
    
    if(TA0CCR2 > TA0CCR0){
        TA0CCR2 = tiempo;
    }
    
    //Reanudar TIMER0
    TA0CTL |= MC__UP;

    //Apagar IFG de CCR1 por si se encendio anteriormente
    TA0CCTL2 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT1);
    
    // Habilitar interrupcion de CCR2
    TA0CCTL2 |= CCIE;

}

void setTimerA0_CCR3(int tiempo){

    //Inicializar TIMER de espera especificado para BMP085 UT
                
    //Stop TIMER0 para leer el valor de TA0R
    TA0CTL &= ~(MC__UP);

    // Comenzar tiempo de espera especificado
    TA0CCR3 = TA0R + tiempo;
    
    // Verificar que no suceda overflow de TA0CCR3 y por tanto
    // nunca sea posible llegar a su cuenta
    if(TA0CCR3 > TA0CCR0){
        TA0CCR3 = tiempo;
    }

    //Reanudar TIMER0
    TA0CTL |= MC__UP;

    //Apagar IFG de CCR1 por si se encendio anteriormente
    TA0CCTL3 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT4);
    
    // Habilitar interrupcion de CCR2
    TA0CCTL3 |= CCIE;

}

void setTimerA0_CCR4(int tiempo){

    //Inicializar TIMER de espera especificado para BMP085 UT
                
    //Stop TIMER0 para leer el valor de TA0R
    TA0CTL &= ~(MC__UP);

    // Comenzar tiempo de espera especificado
    TA0CCR4 = TA0R + tiempo;

    //Reanudar TIMER0
    TA0CTL |= MC__UP;
    
    if(TA0CCR4 > TA0CCR0){
        TA0CCR4 = tiempo;
    }

    //Apagar IFG de CCR1 por si se encendio anteriormente
    TA0CCTL4 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT5);
    
    // Habilitar interrupcion de CCR2
    TA0CCTL4 |= CCIE;

}

void setTimerA1_CCR2(int tiempo){

    //Stop TIMER0 para leer el valor de TA0R
    TA1CTL &= ~(MC__UP);
    
    // Comenzar espera para que XBEE salga de sleep: 3ms
    TA1CCR2 = TA1R + tiempo;
    
    if(TA1CCR2 > TA1CCR0){
        TA1CCR2 = tiempo;
    }
    
    //Reanudar TIMER0
    TA1CTL |= MC__UP;
    
    //Apagar flag de CCR1 por si se encendio anteriormente
    TA1CCTL2 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags2 &= ~(BIT3);
    
    // Habilitar interrupcion
    TA1CCTL2 |= CCIE;

}

void setTimerA2_CCR1(int tiempo){
    //Stop TIMER0 para leer el valor de TA0R
    TA2CTL &= ~(MC__UP);
    
    // Comenzar espera para que XBEE salga de sleep: 3ms
    TA2CCR1 = TA2R + tiempo;
    
    if(TA2CCR1 > TA2CCR0){
        TA2CCR1 = tiempo;
    }
    
    //Reanudar TIMER0
    TA2CTL |= MC__UP;
    
    //Apagar flag de CCR1 por si se encendio anteriormente
    TA2CCTL1 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags2 &= ~(BIT4);
    
    // Habilitar interrupcion
    TA2CCTL1 |= CCIE;  
}

void startMasterReceiveUSCI_B0(unsigned char slave_address, unsigned char number){

    // Cargar direccion de dispositivo esclavo
    UCB0I2CSA = slave_address;

    // Cargar numero de datos que se desea recibir
    SENSOR_RX_EXPECTED = number;
    
    //Indicar que el proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT2);
    
    // Configurar modo recepcion
    UCB0CTL1 &= ~(UCTR);
    
    //Generar condicion start
    UCB0CTL1 |= UCTXSTT;
    
    //Habilitar interrupciones
    UCB0IE |= UCNACKIE + UCRXIE;  

}

char startMasterReceiveUSCI_B0_OneByte(unsigned char slave_address){
    // Cargar direccion de dispositivo esclavo
    UCB0I2CSA = slave_address;

    //Indicar que el proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT2);
    
    // Configurar modo recepcion
    UCB0CTL1 &= ~(UCTR);
    
    //Generar condicion start
    UCB0CTL1 |= UCTXSTT;

    //Esperar a que UCTXSTT = 0
    while(UCB0CTL1 & UCTXSTT){
    }

    // Habilitar envio de STOP condition
    UCB0CTL1 |= UCTXSTP;

    // Esperar a que reciba I2C
    while(!( UCB0IFG & UCRXIFG)){
    }
    
    //Indicar que el proceso no ha terminado, apenas comienza
    procesoTerminadoFlags |= BIT2;
    
    //Termino envio, procesamiento necesario
    LowPowerFlags &= ~(BIT3);

    return UCB0RXBUF;
}


/*
void flashByteWrite(unsigned int *address, char data){
  
    // TODOS LOS ACCESOS A REGISTROS FLASH (FCTLx) DEBEN
    // TENER EL PASSWORD 0xA5 en el byte mas alto
    // O UN PUC es generado
  
 
    // Desbloquear FLASH       
    FCTL3 = FWPW;
    
    // Modo: Byte/Word Write
    FCTL1 = FWPW + WRT;
    
    *address = data;
    
    // Modo: Ninguno
    FCTL1 = FWPW;
    
    // Bloquear FLASH
    FCTL3 = FWPW + LOCK;
    
        
  
  
}
void flashEraseSegment(unsigned int *address){
    
    // TODOS LOS ACCESOS A REGISTROS FLASH (FCTLx) DEBEN
    // TENER EL PASSWORD 0xA5 en el byte mas alto
    // O UN PUC es generado
  
    while( FCTL3 & BUSY );
    
    // Desbloquear FLASH
    FCTL3 = FWPW;
    
    // Configurar Segment Erase
    FCTL1 = FWPW + ERASE;
    
    // Dummy write to segment address to be erased
    *address = 0;
    
    // Modo: Ninguno
    FCTL1 = FWPW;
    
    //Bloquear FLASH
    FCTL3 = FWPW + LOCK;    
  
}
void flashWordWrite(unsigned int *address, unsigned int data){
    
    // TODOS LOS ACCESOS A REGISTROS FLASH (FCTLx) DEBEN
    // TENER EL PASSWORD 0xA5 en el byte mas alto
    // O UN PUC es generado
  
    // Desbloquear FLASH       
    FCTL3 = FWPW;
    
    // Modo: Byte/Word Write
    FCTL1 = FWPW + WRT;
    
    // Ejecutar almacenamiento
    *address = data;

    // Modo: Ninguno
    FCTL1 = FWPW;
    
    // Bloquear FLASH
    FCTL3 = FWPW + LOCK;  
}
*/


void configureACCSensor(char data_format){

    // Indicar que inicia proceso de calibracion de ACC Sensor

    ACC_SENSOR_DATA_FORMAT[1] = data_format;

    calibratingSensor |= BIT1; 
    while(calibratingSensor & BIT1){
        configureACCSensorProc();
        if(calibratingSensor & BIT1){
            P1OUT = BIT3;
            _BIS_SR(LPM1_bits + GIE);
            P1OUT &= ~(BIT3);            
        }

    }


}

void configureACCSensorProc(){

    switch(ACC_SENSOR_CONF_PROCESS_STATE){

        case 0:

            // Esperar que el bus termine
            while( UCB0STAT & UCBBUSY );

            // Transmitir data format: +- 16g, 13bit
            startMasterTransmitUSCI_B0(ACC_SENSOR_ADDRESS, ACC_SENSOR_DATA_FORMAT, 2);
            ACC_SENSOR_CONF_PROCESS_STATE++;
        break;
        case 1:
          if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                // Pasar a siguiente etapa
                ACC_SENSOR_CONF_PROCESS_STATE++;
                
                // Inicilizar Timer para tiempo de espera = 5 ms
                setTimerA0_CCR2(1);  
          
          }
        break;
        case 2:
            //Verificar que transmision anterior haya concluido
            if(procesoTerminadoFlags & BIT1){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                // Iniciar Medicion
                startMasterTransmitUSCI_B0(ACC_SENSOR_ADDRESS, ACC_SENSOR_POWER_CTL, 2);

                ACC_SENSOR_CONF_PROCESS_STATE++;
            }
        break;
        case 3:
            if(procesoTerminadoFlags & BIT0){
                // Salir de calibracion
                calibratingSensor &= ~(BIT1);

                ACC_SENSOR_CONF_PROCESS_STATE=0;
            }
                
        break;
        default:
        break;
    }
}

void sampleACCSensor(void){

    switch(ACC_SENSOR_PROCESS_STATE){

        case 0:

            // Esperar que el bus termine
            while( UCB0STAT & UCBBUSY );
            
            startMasterTransmitUSCI_B0(ACC_SENSOR_ADDRESS, ACC_SENSOR_DATA_ADDRESS, 1);

            ACC_SENSOR_PROCESS_STATE++;
            

            break;
        case 1:
            // Verificar fin de transmision I2C
            if( procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );              
            
                startMasterReceiveUSCI_B0(ACC_SENSOR_ADDRESS, 6);

                ACC_SENSOR_PROCESS_STATE++;
            }           
            break;
        case 2:
            if(procesoTerminadoFlags & BIT2){
                
                ACC_SENSOR_X = (SENSOR_RXBUF[1]<<8) | SENSOR_RXBUF[0];

                ACC_SENSOR_Y = (SENSOR_RXBUF[3]<<8) | SENSOR_RXBUF[2]; 

                ACC_SENSOR_Z = (SENSOR_RXBUF[5]<<8) | SENSOR_RXBUF[4]; 

                //Indicar que ya se puede hacer conversion ASCII de test sensor
                // por que ya esta la muestra
                Flags2 |= BIT4;       

                //Indicar que turno de ACC sensor termino
                Flags2 &= ~BIT5;     
                   
                // Pasar a siguiente sensor (BMP085)
                Flags1 |= BIT6;
            
                // Indicar en LED P1.4
                P1OUT ^= BIT4;
            
                ACC_SENSOR_PROCESS_STATE=0;

            }
            break;

        default:
            break;
    }

}

void getCalibrationDataBMP085(void){


    switch(BMP085_CAL_PROCESS_STATE){

        case 0:

            // Esperar que el bus termine
            while( UCB0STAT & UCBBUSY );            

            startMasterTransmitUSCI_B0(BMP085_ADDRESS, BMP085_CAL_DATA_ADDRESS, 1);

            BMP085_CAL_PROCESS_STATE++;

            break;
        case 1:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );            

                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                BMP085_CAL_PROCESS_STATE++;    
            }
        break;
        case 2:

            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                ac1 = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                startMasterTransmitUSCI_B0(BMP085_ADDRESS,(BMP085_CAL_DATA_ADDRESS+2), 1);

                BMP085_CAL_PROCESS_STATE++;
            }
        break;
        case 3:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                // Pasar a siguiente paso 
                BMP085_CAL_PROCESS_STATE++; 
            }
        break;
        case 4:
            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                ac2 = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                startMasterTransmitUSCI_B0(BMP085_ADDRESS,(BMP085_CAL_DATA_ADDRESS+4),1);
                BMP085_CAL_PROCESS_STATE++;
            }

        break;
        case 5:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );              

                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                BMP085_CAL_PROCESS_STATE++;
            }

        break;
        case 6:
            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                ac3 = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                startMasterTransmitUSCI_B0(BMP085_ADDRESS,(BMP085_CAL_DATA_ADDRESS+6),1);

                BMP085_CAL_PROCESS_STATE++;

            }
        break;
        case 7:

            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                BMP085_CAL_PROCESS_STATE++;
            }
        break;
        case 8:
            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                ac4 = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                startMasterTransmitUSCI_B0(BMP085_ADDRESS,(BMP085_CAL_DATA_ADDRESS+8),1);

                BMP085_CAL_PROCESS_STATE++;
            }
        break;  
        case 9:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );              

                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                BMP085_CAL_PROCESS_STATE++;    

            }

        break;
        case 10:
            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                ac5 = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                startMasterTransmitUSCI_B0(BMP085_ADDRESS,(BMP085_CAL_DATA_ADDRESS+10),1);

                BMP085_CAL_PROCESS_STATE++;
            }

        break;
        case 11:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );              

                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                BMP085_CAL_PROCESS_STATE++;

            //Detener calibracion
            //calibratingBMP085 = 0;
            }
        break;
        case 12:
            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                ac6 = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                startMasterTransmitUSCI_B0(BMP085_ADDRESS,(BMP085_CAL_DATA_ADDRESS+12),1);

                BMP085_CAL_PROCESS_STATE++;
            }
        break;
        
        /*  ******************************************** */
        case 13:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );              

                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                BMP085_CAL_PROCESS_STATE++;

            //Detener calibracion
            //calibratingBMP085 = 0;
            }
        break;
        case 14:
            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                b1 = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                startMasterTransmitUSCI_B0(BMP085_ADDRESS,(BMP085_CAL_DATA_ADDRESS+14),1);

                BMP085_CAL_PROCESS_STATE++;
            }
        break;

        case 15:
            if(procesoTerminadoFlags & BIT0){


                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                BMP085_CAL_PROCESS_STATE++;


            }
        break;
        case 16:
            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                b2 = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                startMasterTransmitUSCI_B0(BMP085_ADDRESS,(BMP085_CAL_DATA_ADDRESS+16),1);

                BMP085_CAL_PROCESS_STATE++;
            }
        break;

        case 17:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );              

                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                BMP085_CAL_PROCESS_STATE++;

            }
        break;
        case 18:
            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                mb = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                startMasterTransmitUSCI_B0(BMP085_ADDRESS,(BMP085_CAL_DATA_ADDRESS+18),1);

                BMP085_CAL_PROCESS_STATE++;
            }
        break;
        case 19:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );              

                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                BMP085_CAL_PROCESS_STATE++;


            }
        break;
        case 20:
            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                mc = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                startMasterTransmitUSCI_B0(BMP085_ADDRESS,(BMP085_CAL_DATA_ADDRESS+20),1);

                BMP085_CAL_PROCESS_STATE++;
            }
        break;
        case 21:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );              

                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                BMP085_CAL_PROCESS_STATE++;

            }
        break;
        case 22:
            if(procesoTerminadoFlags & BIT2){
                md = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                BMP085_CAL_PROCESS_STATE=0;

                //Detener calibracion
                calibratingSensor &= ~(BIT0);
            }
        break;
        default: break;

    }

}

void getCalBMP085(void){
    calibratingSensor |= BIT0; 
    while(calibratingSensor &  BIT0){
        getCalibrationDataBMP085();
        if(calibratingSensor & BIT0){
            P1OUT = BIT3;
            _BIS_SR(LPM1_bits + GIE);
            P1OUT &= ~(BIT3);            
        }

    }

}

void getUT_BMP085(void){

    switch(BMP085_UT_PROCESS_STATE){

        case 0:

            // Esperar que el bus termine
            while( UCB0STAT & UCBBUSY );

            // Escribir a BMP085 para obtener UT
            startMasterTransmitUSCI_B0(BMP085_ADDRESS, BMP085_UT_DATA, 2);

            // Pasar a siguiente paso
            BMP085_UT_PROCESS_STATE++;

        break;
        case 1:
            if(procesoTerminadoFlags & BIT0){

                // Esperar ~4.5ms
                setTimerA0_CCR3(42);

                // Siguiente paso
                BMP085_UT_PROCESS_STATE++;

            }
        break;
        case 2:
            // Verificar si ya termino tiempo de espera de 4.5ms con TA0-CCR3
            if(procesoTerminadoFlags & BIT4){

                // Escribir a BMP085 para obtener UT
                startMasterTransmitUSCI_B0(BMP085_ADDRESS, BMP085_UT_DATA_ADDRESS, 1);

                // Siguiente paso
                BMP085_UT_PROCESS_STATE++;

            }
        break;
        case 3:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                // Recibir dos bytes (en este caso se esperan los ubicados en 0xF6,0xF7 del BMP085)
                startMasterReceiveUSCI_B0(BMP085_ADDRESS,2);

                //Siguiente paso
                BMP085_UT_PROCESS_STATE++; 
            }

        break;
        case 4:
            if(procesoTerminadoFlags & BIT2){
                //Formar UT a partir de los bytes recibidos.
                BMP085_UT = (SENSOR_RXBUF[0]<<8) + SENSOR_RXBUF[1];

                // Resetear proceso
                BMP085_UT_PROCESS_STATE = 0;

                //Pasar a siguiente sensor (BMP085_UP)
                Flags1 |= BIT7;

                //Indicar que la muestra de UT ya esta lista
                Flags2 |= BIT2;

                // Indicar que acabo turno de getUP_BMP085()
                Flags1 &= ~BIT6; 
            }

        break;
        default:break;


    }
}

void getUP_BMP085(void){

       switch(BMP085_UP_PROCESS_STATE){

        case 0:

            // Esperar que el bus termine
            while( UCB0STAT & UCBBUSY );

            //P4OUT |= BIT0;
            // Escribir a BMP085 para obtener UT
            startMasterTransmitUSCI_B0(BMP085_ADDRESS, BMP085_UP_DATA, 2);

            // Pasar a siguiente paso
            BMP085_UP_PROCESS_STATE++;

        break;
        case 1:
            if(procesoTerminadoFlags & BIT0){

                // Esperar el tiempo correspondiente segun
                // el valor de OSS
                setTimerA0_CCR4( 19 + (28 << BMP085_OSS) );

                // Siguiente paso
                BMP085_UP_PROCESS_STATE++;

            }
        break;
        case 2:
            // Verificar si ya termino tiempo de espera de 4.5ms con TA0-CCR3
            if(procesoTerminadoFlags & BIT5){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                // Escribir a BMP085 para obtener UT
                startMasterTransmitUSCI_B0(BMP085_ADDRESS, BMP085_UP_DATA_ADDRESS, 1);

                // Siguiente paso
                BMP085_UP_PROCESS_STATE++;

            }
        break;
        case 3:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                // Recibir dos bytes (en este caso se esperan los ubicados en 0xF6,0xF7 del BMP085)
                startMasterReceiveUSCI_B0(BMP085_ADDRESS,3);

                //Siguiente paso
                BMP085_UP_PROCESS_STATE++; 
            }

        break;
        case 4:
            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                //Formar UT a partir de los bytes recibidos.
                BMP085_UP = (SENSOR_RXBUF[0]);
                BMP085_UP = BMP085_UP << 8;
                BMP085_UP |= (SENSOR_RXBUF[1]);
                BMP085_UP = BMP085_UP << 8;
                BMP085_UP |= SENSOR_RXBUF[2];
                BMP085_UP  = BMP085_UP >> (8-BMP085_OSS);


                //Indicar que la muestra de UP ya esta lista
                Flags2 |= BIT3;

                // Resetear proceso
                BMP085_UP_PROCESS_STATE = 0;

                // Indicar que es turno de getPacketCount
                Flags3 |= BIT5;

                // Indicar que ya no es turno de BMP085 UP
                Flags1 &= ~BIT7; 

                /*
                // Indicar que ya se muestrearon sensores 
                // Esto lo debe indicar siempre el ultimo sensor
                Flags1 &= ~(BIT2);
                
                // Indicar que ya no es turno de BMP085 UP
                Flags1 &= ~BIT7; 

                //P4OUT &= ~(BIT0);

                */
            }
        break;
        default:break;
    }
}

void startPCTransmission(unsigned char *array, char longitud){

      // Inicializar variables de transmision
    PC_TXBUF = array;
    PC_TXBUF_LENGTH = longitud;

    
    //Indicar que este proceso ha terminado, apenas comienza  (verificar la necesidad de esta bandera)
    //procesoTerminadoFlags &= ~(BIT3);   
    
    // Comenzar transmision habilitando UCA0SWRST
    //Deshabilitar y Habilitar USCI_A0
    //UCA0CTL1 |= UCSWRST;    
    // Habilitar interrupcion de TX
    UCA1IE |= UCTXIE;
    
    //  Indicar que transmision esta en curso
    MFlags1 |= BIT1;

}

void readByteExternalEEPROM2(char deviceAddress, unsigned char *address){

    switch(EXTERNAL_MEMORY_BYTEREAD_PROC){

        case 0:


            // Esperar que el bus termine
            while( UCB0STAT & UCBBUSY );

            // Enviar posicion de memoria a leer
            startMasterTransmitUSCI_B0(deviceAddress, address, 2);

            EXTERNAL_MEMORY_BYTEREAD_PROC++;
            
        break;

        case 1:
            // Verificar que proceso de lectura haya terminado
            if(procesoTerminadoFlags & BIT0){
                
                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );
              
                // Recibir byte y almacenar
                SENSOR_RXBUF[0] = startMasterReceiveUSCI_B0_OneByte(deviceAddress);

                //Siguiente paso
                EXTERNAL_MEMORY_BYTEREAD_PROC++;
            }
        break;
        case 2:
          // Verificar que proceso de lectura haya terminado
          if(procesoTerminadoFlags & BIT2){
               // Terminar proceso  
              EXTERNAL_MEMORY_BYTEREAD_PROC = 0; 
          }
        break;
        default:
        break;

    }

}

void writeByteExternalEEPROM2(char memoryAddress, unsigned char *address_data){

    switch(EXTERNAL_MEMORY_BYTEWRITE_PROC){
    case 0:
        
        // Esperar que el bus termine
        while( UCB0STAT & UCBBUSY );

        startMasterTransmitUSCI_B0(memoryAddress, address_data, 3);        
        EXTERNAL_MEMORY_BYTEWRITE_PROC++;
        
        break;
    case 1:
        if(procesoTerminadoFlags & BIT0){
              
            // Esperar 5ms de escriture de EEPROM
            setTimerA2_CCR1(46);
            // Resetear proceso
            EXTERNAL_MEMORY_BYTEWRITE_PROC ++;
        }
            
        break;
    case 2:
        // Verificar que Timer haya concluido
        if(procesoTerminadoFlags2 & BIT4){
          
            EXTERNAL_MEMORY_BYTEWRITE_PROC = 0;
            
        }
        break;
        
    default:
        break;
    }
}

void guardarPaqueteMemoriaExterna(void){

    switch(  guardarPaqueteCFSW_PROC ){
        // Obtener direccion en memoria externa para
        // continuar almacenamiento
        case 0:
            // Obtener direccion en memoria externa para
            // continuar almacenamiento

            getNextWritableAddressExternalMemory();

            guardarPaqueteCFSW_PROC ++;


        break;

        case 1:

            getNextWritableAddressExternalMemory();

            // Verificar que se haya terminado getNextWritableAddressExternalMemory
            if(procesoTerminadoFlags2 & BIT0){

                // Guardar datos en memoria externa desde numero de paquetes enviados
                // hasta FSW state.

                // Verificar que memoria externa no este llena

                if( ! ( Flags3 & BIT2 ) ){
                    // Guardar datos en memoria externa desde numero de paquetes enviados
                    // hasta FSW state.
                    saveDataToExternalMemory(NextWritableAddress, (PFSW_TransPackage +PACKET_COUNT_OFFSET), TELEMETRY_DATAPACKET_LENGTH );
                    
                    // Siguiente paso
                    guardarPaqueteCFSW_PROC++;
                    
                }else{

                  // Encender LEDS de memoria llena
                    updateNextWritableAddress();

                  // Saltar el siguiente paso e ir a 3 directamente.  
                    guardarPaqueteCFSW_PROC = 3;

                }
                

            }
        break;
        
        case 2:

            // Actualizar siguiente posicion de memoria disponible
            updateNextWritableAddress();
            guardarPaqueteCFSW_PROC++;

        break;
        case 3:
            updateNextWritableAddress();

            // Verificar que updateNextWritableAddress termine
            if( procesoTerminadoFlags2 & BIT1 ){

                // Indicar que guardado de paquete en memoria externa ha terminado
                Flags4 &= ~BIT2;
              

            
                // 
                guardarPaqueteCFSW_PROC = 0;
            
                // Indicar que procesamiento principal cada segundo termina aqui
                Flags3 &= ~BIT3;
            
                
                


                //Apagar LED de 1s
                P1OUT &= ~(BIT2);
                


                //Requerir nueva indicacion de paquete listo
                datosListosFlags &= ~(BIT6 + BIT5 + BIT4 + BIT3 + BIT2 + BIT1 + BIT0);

                //Resetear bandera de datos para conversion a ASCII listos
                // BIT2: BMP085 UT
                // BIT4: ACC Sensor
                // BIT3: BMP085 UP
                // BIT0: Voltaje
                Flags2 &= ~(BIT4 + BIT3 + BIT2 + BIT0);

                // Flags3.7 = Packet Count
                Flags3 &= ~BIT7;

                //Flags4.4 = MissionTime
                Flags4 &= ~(BIT4);
                

                // Resetear banderas de inicio de procesos de muestreo
                // para siguiente ronda de muestreo
                procesoIniciadoFlags &= ~(BIT0);    //Bandera ADC

                


            }

        break;
        default:
        break;
    }
} 

void getNextWritableAddressExternalMemory(void){

    switch(getNextWritableAddress_PROC){

        case 0:  

            // Esperar que el bus termine
            while( UCB0STAT & UCBBUSY );


            // Indicar que proceso de getNextWritableAddress esta comenzando
             procesoTerminadoFlags2 &=  ~BIT0;
            // Put Higher Byte of Address to Write first
            EXTERNAL_MEMORY_TX_BUFFER[0] = NEXT_AVAILABLE_EEPROM_ADDRESS>>8;
            EXTERNAL_MEMORY_TX_BUFFER[1] = NEXT_AVAILABLE_EEPROM_ADDRESS;

            // Direccionar memoria
            startMasterTransmitUSCI_B0(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 2);

            getNextWritableAddress_PROC++;

        break;
        case 1:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );

                // Recibir direccion
                startMasterReceiveUSCI_B0(EXTERNAL_MEMORY_ADDRESS, 2);

                // Siguiente paso
                getNextWritableAddress_PROC++;
            }
        break;
        case 2:
            if(procesoTerminadoFlags & BIT2){

                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );              

                // Armar direccion
                NextWritableAddress = SENSOR_RXBUF[0];
                NextWritableAddress = NextWritableAddress<<8;
                NextWritableAddress += SENSOR_RXBUF[1];
                getNextWritableAddress_PROC = 0;

                // Indicar que termino proceso de getNextWritableAddress
                procesoTerminadoFlags2 |=  BIT0;
            }
        break;
        default:
        break;
    }
}


void saveDataToExternalMemory(int address, unsigned char *datos, unsigned char length){

    
    // Primer direccion disponible en memoria
    int initialAddress = address;

    // Siguiente limite de pagina
    int nextPageStartAddress;   

    // puntero a los bytes de la direccion donde se comenzara a escribir
    unsigned char *addressByte;
    //addressByte++;

    //char *nibbleAddressByte;
    //nibbleAddressByte = addressByte;

    // Contiene la cantidad de bytes almacenados
    char bytesSaved = 0;


    //
    char newLength = length;

    // Numero de caracteres a copiar
    char copyCounter = 0;

    char a = 0;

    do{

        nextPageStartAddress = (initialAddress & 0xFFC0) + 64;


        // Copiar direccion en donde comenzara almacenamiento al buffer de escritura 
        addressByte = (unsigned char *) &initialAddress;
        // Almacenar LSB de Direccion a escribir en Buffer
        EXTERNAL_MEMORY_TX_BUFFER[1] = (*addressByte);
        // Apuntar a MSB
        addressByte++;
        // Almacenar MSB en direccion a escribir en buffer
        EXTERNAL_MEMORY_TX_BUFFER[0] = (*addressByte);


        // Verificar a que direccion se llegaria despues de almacenar los paquetes necesario
        if( (initialAddress + newLength -1) >= nextPageStartAddress  ){     // Direccion final esta en siguiente pagina?

            // Enviar paquetes por separado
            // 1.- Enviar paquetes desde la direccion initialAddress hasta (initialAddress + length -1)
            // 2.- Repetir ciclo de verificacion

            copyCounter = nextPageStartAddress - initialAddress;

            // Copiar datos de matriz origen a matriz para enviar datos I2C a Memoria Externa
            for( a= 0; a < copyCounter; a++){

                // Offset de 2 en MEMORY_TX_BUFFER por que en las primeras dos posiciones esta la direccion
                // datos[ a + bytesSaved] por que bytesSaved devuelve el offset a partir de la posicion 0
                // de "datos" en donde se encuentran los siguientes datos a copiar
                EXTERNAL_MEMORY_TX_BUFFER[a + 2] = datos[ a + bytesSaved];
            }

            do{
                                                                                                    // Son 2 bytes mas por la direccion al inicio
                writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, copyCounter + 2);

            }while(EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);

            // Se escribio hasta el final de la pagina actual, entonces apunter a siguiente pagina
            initialAddress = nextPageStartAddress;
            // Actualizar numero de datos guardados
            bytesSaved += copyCounter;
            // La longitud de los datos restantes a guardar ha cambiado
            newLength -= copyCounter;



        }else{

            for( a= 0; a < newLength; a++){

                // Offset de 2 en MEMORY_TX_BUFFER por que en las primeras dos posiciones esta la direccion
                // datos[ a + bytesSaved] por que bytesSaved devuelve el offset a partir de la posicion 0
                // de "datos" en donde se encuentran los siguientes datos a copiar
                EXTERNAL_MEMORY_TX_BUFFER[a + 2] = datos[ a + bytesSaved];
            }

            // Enviar todod el paquete de un solo
            do{

                writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS,EXTERNAL_MEMORY_TX_BUFFER, newLength+2);

            }while(EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);

            bytesSaved += newLength;
        }
    
    }while( bytesSaved < length);


    // Actualizar siguiente direccion disponible en memoria EEPROM
    NextWritableAddress += length;

    if( (NextWritableAddress + length ) > 0x3FFF){

        // Indicar que memoria externa esta llena
        Flags3 |= BIT2;

    }
} 

void writePacketExternalEEPROM_24XX(char memoryAddress, unsigned char *address_data, unsigned char length){

    switch(EXTERNAL_MEMORY_PACKETWRITE_PROC){
    case 0:

        // Indicar que este proceso esta comenzando
        procesoTerminadoFlags &= ~(BIT7);

        startMasterTransmitUSCI_B0(memoryAddress, address_data, length);        
        EXTERNAL_MEMORY_PACKETWRITE_PROC++;
        
        break;
    case 1:
        if(procesoTerminadoFlags & BIT0){
              
            // Esperar 5ms de escriture de EEPROM
            setTimerA1_CCR2(46);
            // Resetear proceso
            EXTERNAL_MEMORY_PACKETWRITE_PROC ++;
        }
            
        break;
    case 2:
        // Verificar que Timer haya concluido
        if(procesoTerminadoFlags2 & BIT3){
          
            EXTERNAL_MEMORY_PACKETWRITE_PROC = 0;

            // Indicar que termino el proceso de escritura de paquete en memoria externa
            procesoTerminadoFlags |= BIT7;
            
        }
        break;
    default:
        break;
    }
}              
              
void updateNextWritableAddress(){
    unsigned char *point =(unsigned char *) &NextWritableAddress;
  
    switch(updateNextWritableAddress_PROC){

        case 0:


            // Indicar que  proceso de getNextWritableAddress apenas comienza
            procesoTerminadoFlags2 &=  ~BIT1;

            EXTERNAL_MEMORY_TX_BUFFER[0] = NEXT_AVAILABLE_EEPROM_ADDRESS >> 8;
            EXTERNAL_MEMORY_TX_BUFFER[1] = NEXT_AVAILABLE_EEPROM_ADDRESS;
            point = (unsigned char *) &NextWritableAddress;
            EXTERNAL_MEMORY_TX_BUFFER[3] = (*point);
            point++;
            EXTERNAL_MEMORY_TX_BUFFER[2] = (*point);

            writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);
            
          
            updateNextWritableAddress_PROC ++;
            

        break;
        case 1:
            writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);
            // Verificar que proceso de escritura en memoria externa haya terminado
            if(procesoTerminadoFlags & BIT7){
                
                updateNextWritableAddress_PROC = 0;
                // Indicar que termino proceso de updateNextWritableAddress
                procesoTerminadoFlags2 |=  BIT1;
            }

        break;

        default:
        break;
    }
  
}

void getPacketCount(void){

    switch(XBEE_PACKET_RETRIEVE_PROC){

        case 0:

            // Calcular puntero en memoria externa hacia direccion de 
            // paquetes
            EXTERNAL_MEMORY_TX_BUFFER[0] = PACKET_COUNT_EEPROM_ADDRESS>>8;
            EXTERNAL_MEMORY_TX_BUFFER[1] = PACKET_COUNT_EEPROM_ADDRESS;

            readPacketExternalEEPROM( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 2);

            XBEE_PACKET_RETRIEVE_PROC++;

        break;
        case 1:

            readPacketExternalEEPROM( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 2);

            // Verificar que proceso haya concluido
            if( procesoTerminadoFlags2 & BIT5 ){


                XBEE_TXBUF_COUNTER = SENSOR_RXBUF[0];
                XBEE_TXBUF_COUNTER = XBEE_TXBUF_COUNTER<<8;
                XBEE_TXBUF_COUNTER += SENSOR_RXBUF[1];

                // Incrementar cuenta de paquetes enviados
                XBEE_TXBUF_COUNTER++;
                if(XBEE_TXBUF_COUNTER > 9999){
                  XBEE_TXBUF_COUNTER = 9999;
                }

                XBEE_PACKET_RETRIEVE_PROC = 0;


                // Indicar que ya esta listo el packetCount
                Flags3 |= BIT7;
                
                // Indicar que ya termino el turno de getPacketCount
                Flags3 &= ~BIT5;

                // Indicar que es turno de getMissionTime
                Flags4 |= BIT3;

                // Indicar que ya termino la ronda de muestreo de sensores
                // Esto lo debe indicar siempre el ultimo sensor
               // Flags1 &= ~(BIT2);



            }
        break;
        default:
        break;
    }
}

void readPacketExternalEEPROM(char deviceAddress, unsigned char *address, unsigned char length){

    switch(EXTERNAL_MEMORY_PACKETREAD_PROC){

        case 0:

            // Esperar que el bus termine
            while( UCB0STAT & UCBBUSY );


            // Indicar que este proceso apenas comienza
            procesoTerminadoFlags2 &= ~(BIT5);

            // Enviar posicion de memoria a leer
            startMasterTransmitUSCI_B0(deviceAddress, address, 2);

            EXTERNAL_MEMORY_PACKETREAD_PROC++;
            
        break;

        case 1:
            // Verificar que proceso de lectura haya terminado
            if(procesoTerminadoFlags & BIT0){
              
                // Esperar que el bus termine
                while( UCB0STAT & UCBBUSY );
                // Recibir byte y almacenar
                startMasterReceiveUSCI_B0(deviceAddress, length);

                //Siguiente paso
                EXTERNAL_MEMORY_PACKETREAD_PROC++;
            }
        break;
        case 2:
          // Verificar que proceso de lectura haya terminado
          if(procesoTerminadoFlags & BIT2){

              // Esperar que el bus termine
              while( UCB0STAT & UCBBUSY );

               // Terminar proceso  
              EXTERNAL_MEMORY_PACKETREAD_PROC = 0; 

              // Indicar que este proceso ha terminado
              procesoTerminadoFlags2 |= BIT5;
          }
        break;
        default:
        break;

    }

}

void initExternalMemory(void){

    unsigned int dummy;
    unsigned char * pointer;


    // Initialize Next Writable Address

    dummy = NEXT_AVAILABLE_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[1] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[0] = *pointer;

    dummy = FIRST_AVAILABLE_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[3] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[2] = *pointer;


    // Write Data to Memory
    do{
        writePacketExternalEEPROM_24XX( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);
    }while( EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);


    // Initialize Mission Time
    dummy = MISSION_TIME_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[1] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[0] = *pointer;

    EXTERNAL_MEMORY_TX_BUFFER[3] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[2] = 0;

    do{
        writePacketExternalEEPROM_24XX( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4); 
    }while( EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);
    // Initialize Packet Count
    dummy = PACKET_COUNT_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[1] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[0] = *pointer;

    EXTERNAL_MEMORY_TX_BUFFER[3] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[2] = 0;

    do{
        writePacketExternalEEPROM_24XX( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4); 
    }while( EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);
    // Initialize CFSW State Variable
    dummy = CFSW_STATE_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[1] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[0] = *pointer;

    EXTERNAL_MEMORY_TX_BUFFER[3] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[2] = 0;

    do{
        writePacketExternalEEPROM_24XX( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 3); 
    }while( EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);
    // Initialize Last Pressure
    dummy = LAST_PRESSURE_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[1] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[0] = *pointer;

    EXTERNAL_MEMORY_TX_BUFFER[3] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[2] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[4] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[5] = 0;

    do{
        writePacketExternalEEPROM_24XX( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 6);
    }while( EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);
    

    // Indicar que memoria externa se encuentra vacia
    Flags3 &= ~BIT2;
    
}

void armarPaquetePFSW(unsigned char* array){

    // Actualizar Packet Count
    do{
        getPacketCount();
    }while(XBEE_PACKET_RETRIEVE_PROC);
    // Reducir packetCount por que getPacketCount() aumenta en 1
    XBEE_TXBUF_COUNTER--;
    packetCountBinaryToASCII(XBEE_TXBUF_COUNTER, array, PACKET_COUNT_OFFSET);

    // Actualizar mission time
    do{
      getMissionTime();
    }while( RTC_getMissionTime_PROC );
    rtcBinaryToASCII(missionTimeSeconds, array, MISSION_TIME_OFFSET);


    // Sample pressure
    do{
      getUP_BMP085(); 
    } while(BMP085_UP_PROCESS_STATE);
    presSensorBinaryToASCII(BMP085_UP, array, PRES_SENSOR_OFFSET);

    // Sample Temperature
    do{
      getUT_BMP085();
    }while(BMP085_UT_PROCESS_STATE);
    tempSensorBinaryToASCII(BMP085_UT, array, TEMP_SENSOR_OFFSET);

    // Sample voltage
    sampleADC();
    // Esperar a que la muestra sea tomada
    while( !(Flags2 & BIT0) );
    Flags2 &= ~BIT0;
    voltageBinaryToASCII(VOLTAJE_ADC, array, VOLTAGE_OFFSET);

    // Sample Acceleration
    
    
    do{
        sampleACCSensor();
    }while(ACC_SENSOR_PROCESS_STATE);
    
    accSensorXBinaryToASCII(ACC_SENSOR_X, array, ACC_X_OFFSET);
    accSensorXBinaryToASCII(ACC_SENSOR_Y, array, ACC_Y_OFFSET);
    accSensorXBinaryToASCII(ACC_SENSOR_Z, array, ACC_Z_OFFSET);


}


void eraseExternalMemoryComplete(void){

    unsigned int start_erase_address = 0;
    
    // Sincronizar contadores de escritura
    NextWritableAddress = 0;
    unsigned char a = 0;
    unsigned char *point = (unsigned char * ) &start_erase_address;

    // Indicar que memoria no esta llena
    Flags3 &= ~BIT2;


    // Borrar memoria desde start_erase_address hasta el punto en el que
    // el puntero a memoria se encuentre a 23 posiciones del final
    while( !(Flags3 & BIT2) ){

        for(a= 2; a < 25; a++){
            // El caracter de sector vacÃ­o es OxFF
            EXTERNAL_MEMORY_TX_BUFFER[a]=0xFF;
        }


        saveDataToExternalMemory(start_erase_address, EXTERNAL_MEMORY_TX_BUFFER + 2, 23);
        start_erase_address += 23;

    }


    // Borrar las ultimas 3 posiciones
    for( start_erase_address; start_erase_address <= 0x3FFF; start_erase_address++){

        EXTERNAL_MEMORY_TX_BUFFER[1] = *point;
        point++;
        EXTERNAL_MEMORY_TX_BUFFER[0] = *point;
        point--;
        EXTERNAL_MEMORY_TX_BUFFER[2] = 0xFF;


        do{
            writeByteExternalEEPROM2(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER);
        }while(EXTERNAL_MEMORY_BYTEWRITE_PROC != 0);

    }
    

}

void savePacketCount(void){

    // Apuntar a bytes de Cuenta de Paquetes
    unsigned char *dummy_point = (unsigned char *)&XBEE_TXBUF_COUNTER;

    switch(XBEE_PACKET_SAVE_PROC){

        case 0:

            EXTERNAL_MEMORY_TX_BUFFER[0] = PACKET_COUNT_EEPROM_ADDRESS>>8;
            EXTERNAL_MEMORY_TX_BUFFER[1] = PACKET_COUNT_EEPROM_ADDRESS;
            // Almacenar LSB
            EXTERNAL_MEMORY_TX_BUFFER[3] = *(dummy_point);
            dummy_point++;
            EXTERNAL_MEMORY_TX_BUFFER[2] = *(dummy_point);

            // Escribir en memoria eeprom
            writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);

            XBEE_PACKET_SAVE_PROC++;

        break;
        case 1:

            //  Seguir escribiendo en memoria
            writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);


            // Verificar si termino escritura
            if( procesoTerminadoFlags & BIT7 ){

                XBEE_PACKET_SAVE_PROC = 0;
                
                // Indicar que turno de savePacketCount ha terminado
                Flags3 &= ~BIT0;
                
                // Indicar que es turno de guardarPaqueteMemoriaExterna
                Flags4 |= BIT2;

            }

        break;
        default:
        break;

    }

}



void getMissionTime(void){

  char minutos = 0;
  char horas = 0;
  switch(RTC_getMissionTime_PROC){

      case 0:

          // Esperar que el bus este desocupado
          while(UCB0STAT & UCBBUSY);   

          // Primer direccion a leer es segundos
          SENSOR_TX_BUFFER[0] = 0x00;
          // Enviar direccion
          startMasterTransmitUSCI_B0(RTC_ADDRESS, SENSOR_TX_BUFFER, 1);

          // Avanzar a siguiente paso
          RTC_getMissionTime_PROC++;          

          break;
      case 1:

          // Verificar fin de envio anterior y bus desocupado
          if( (procesoTerminadoFlags & BIT0) ){

              // Esperar que el bus termine
              while( UCB0STAT & UCBBUSY );
              // Recibir 7 bytes: segundos, minutos, horas, dia, fecha, mes, año
              startMasterReceiveUSCI_B0(RTC_ADDRESS, 7);
              // Siguiente paso
              RTC_getMissionTime_PROC++;

          }
          break;
      case 2:

          if(procesoTerminadoFlags & BIT2){

              while( UCB0STAT & UCBBUSY );
              // Anadir unidades de segundo
              missionTimeSeconds = (SENSOR_RXBUF[0] & 0x0F);
              // Anadir decenas de segundo
              missionTimeSeconds += ((SENSOR_RXBUF[0]>>4) & 0x07)*10;

              // Calcular total de minutos
              // Anadir unidades de minutos
              minutos = (SENSOR_RXBUF[1] & 0x0F);
              // Anadir decenas de minutos
              minutos += (( SENSOR_RXBUF[1]>>4 ) & 0x07)*10;

              // Anadir segundos correspondientes a total de minutos transcurridos
              missionTimeSeconds += (minutos)*60;

              //Calcular total de horas
              //Anadir unidades de horas
              horas = (SENSOR_RXBUF[2] & 0x0F);              
              //Anadir decenas de horas
              horas = ((SENSOR_RXBUF[2]>>4) & 0x03)*10;

              //Anadir segundos correspondientes al total de horas transcurridas
              missionTimeSeconds += horas*3600;


              //Proceso Terminado
              RTC_getMissionTime_PROC = 0;

              // Ya no es turno de getMissionTime
              Flags4 &= ~BIT3;

              // Ya esta listo el tiempo de mision
              Flags4 |= BIT4;


              // Indicar que ya termino la ronda de muestreo de sensores
              // Esto lo debe indicar siempre el ultimo sensor
              Flags1 &= ~(BIT2);

          }
          break;
      case 3:
          break;
      case 4:
          break;
      default:
          break;



  }

}


void getMissionTimeSeconds(void){
}
void getMissionTimeMinutes(void){
}
void getMissionTimeHours(void){
}
void setMissionTime(void){

    //char counter = 0;
    switch(RTC_setMissionTime_PROC){

        case 0:
              /*
              // Inicializar minutos, horas, segundos y dias en 0
              for(counter = 0; counter<10; counter++){
                  SENSOR_TX_BUFFER[counter] = 0;
              }
              */
              // Primer direccion a cargar es minutos
              SENSOR_TX_BUFFER[0]=0x01;
              // 0 minutos
              SENSOR_TX_BUFFER[1]=0;
              // 0 horas, formato 24 horas
              SENSOR_TX_BUFFER[2]=0;
              // Dia 1, 
              SENSOR_TX_BUFFER[3]=0x01;
              // Fecha: dia 13
              SENSOR_TX_BUFFER[4]=0x13;
              // Mes: 06 (junio)
              SENSOR_TX_BUFFER[5]=0x06;
              // Año: 14
              SENSOR_TX_BUFFER[6]=0x14;
              // Habilitar SQWE, Frecuencia 1Hz
              SENSOR_TX_BUFFER[7]= RTC_SQWE + RTC_MFP_1HZ;
              
              // Esperar que el bus este desocupado
              while(UCB0STAT & UCBBUSY);              
              
              startMasterTransmitUSCI_B0(RTC_ADDRESS, SENSOR_TX_BUFFER, 8);

              RTC_setMissionTime_PROC++;

            break;
        case 1:

              // Verificar que transmicion I2C haya terminado
              if( (procesoTerminadoFlags & BIT0) && (!(UCB0STAT & UCBBUSY)) ){
                  // Direccion a cargar es segundos
                  SENSOR_TX_BUFFER[0]=0x00;
                  // 0 segundos
                  SENSOR_TX_BUFFER[1]= 0 + RTC_START;

                  startMasterTransmitUSCI_B0(RTC_ADDRESS, SENSOR_TX_BUFFER, 2);

                  RTC_setMissionTime_PROC++;
              }

            break;
        case 2:
              // Verificar que transmicion I2C haya terminado
              if( procesoTerminadoFlags & BIT0 && (!(UCB0STAT & UCBBUSY))){

                  RTC_setMissionTime_PROC = 0;
              }

              break;
        default:
            break;


    }

}



void main (void){

    int dummy_counter1 = 0x0000;
    int* pointer1 = &ac1;

    configureWDT();
    configureIOPorts();
    configurePortMappingPins();
    configureClocks();
    
    //Verify XT1CLK initialized correctly after Clocks Initialization   
    do{      
        // Clear XT2,XT1,DCO fault flags
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
        // Clear fault flags
        SFRIFG1 &= ~OFIFG;    
    }while(SFRIFG1 & OFIFG);     //while OFIFG = 1
        
    configureADC12A();
    configureREF(); 
    configureUSCI_A0();
    configureUSCI_A1();
    configureUSCI_B0();
    getCalBMP085();
    configureTimerA0();
    configureTimerA1();
    configureTimerA2();
    //configureTimerB0();
    //configureSystem();    
    
    // Configuracion de Acelerometro SIEMPRE despues 
    // de configuración de TimerA0, por que lo utiliza
    configureACCSensor(0x01);


    
    
    //Reduce 32.768kHz XTAL on XT1 Drive Strength
    //reduceXT1_XTAL_DriveStrength();

    
   // unsigned int *infoB = (unsigned int*) FLASH_INFO_SEGMENT_B;
    
    //flashWordWrite(infoB, 0xCDEA);
    //flashLongWordWrite(infoB, 0x0000CDEA);
    //flashEraseSegment(infoB);


    

    //Habilitar entrada a LPM
    LowPowerFlags = (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7 );
    LowPowerFlags2 = (BIT0 + BIT1 + BIT2);

   
    while(1){
       

      // Modo de Vuelo
      while(modo != 0xAA){

        while(Flags3 & BIT3){
          
            if(Flags1 & BIT2){       // Verificar si se pueden muestrear sensores
              
                //Si aun no se ha tomado muestra
                if(!(procesoIniciadoFlags & BIT0)){
                    sampleADC();
                }
                

                
                // Muestrear sensor de aceleracion
                // ¿Aun no esta lista la muestra
                if( (Flags2 & BIT5) ){
                
                    LowPowerFlags |= (BIT1 + BIT3);
                    sampleACCSensor();
                    
                    /*
                    //Indicar que ya se puede hacer conversion ASCII de test sensor
                    // por que ya esta la muestra
                    Flags2 |= BIT4;       

                    //Indicar que turno de ACC sensor termino
                    Flags2 &= ~BIT5;     
                       
                    // Pasar a siguiente sensor (BMP085)
                    Flags1 |= BIT6;
                
                    // Indicar en LED P1.4
                    P1OUT ^= BIT4;
                    */
                }

                //   ¿ Turno de UT_BMP085?   
                if(    ( Flags1 & BIT6 )   ) {

                    // Procesamiento de TIMERA0_CCR3, I2C_TX, I2C_RX  permite modo sleep
                    LowPowerFlags |= (BIT6 + BIT1 + BIT3);

                    // Obtener Temperatura sin compensacion
                    getUT_BMP085();

                }

                //   ¿ Turno de UP_BMP085?
                if(     (Flags1 & BIT7 ) ){

                    // Procesamiento de TIMERA0_CCR4, I2C_TX, I2C_RX  permite modo sleep
                    LowPowerFlags |= (BIT7 + BIT1 + BIT3);

                    // Obtener temperatura con compensacion
                    getUP_BMP085();

                }

                //  Es el turno ya/aun de getPacketCount?   
                if( Flags3 & BIT5 ){

                    LowPowerFlags |= ( BIT1 + BIT3);
                  
                    // Obtener cuenta de numero de paquetes
                    // La almacena automaticamente en XBEE_TX_COUNT
                    getPacketCount();

                }


                if( Flags4 & BIT3 ){

                    // Procesamiento de I2C_TX
                    LowPowerFlags |= (BIT1 + BIT3);

                    // Obtener tiempo de mision
                    getMissionTime();

                }


            }
          
            if( Flags1 & BIT0){     // Verificar si se recibio en XBEE_RXBUF
                // Blinkear P4.7
                P4OUT ^= BIT7;    
                
                // Indicar que ya se proceso recepcion XBEE_RXBUFF
                Flags1 &= ~(BIT0);
                
            }     


            
           // Actualizacion y Conversion ASCII de PACKET COUNT
            if((Flags3 & BIT7) &&  (!(datosListosFlags & BIT5))){
                
                //Incrementar cuenta de paquete
                //XBEE_TXBUF_COUNTER++;
                
                // Añadir al paquete
                packetCountBinaryToASCII(XBEE_TXBUF_COUNTER, PFSW_TransPackage, PACKET_COUNT_OFFSET);
                
                // Indicar que ya esta listo en el paquete de datos
                datosListosFlags |= BIT5;
                
            }
            
            // Conversion ASCII de voltaje
            if( (Flags2 & BIT0)  && (!(datosListosFlags & BIT1)) ){    // Verificar si se puede hacer conversion binario -> ASCII de voltaje  
              
                // Hacer conversion a ASCII y alocar en PSFW Package
                voltageBinaryToASCII(VOLTAJE_ADC, PFSW_TransPackage, VOLTAGE_OFFSET);
                
                // Ya se realizo conversion, apagar bandera
                //Flags2 &= ~(BIT0);   
                
                //Indicar que ya esta listo en PFSW_Package el voltaje
                datosListosFlags |= BIT1;
                
                //Permitir entrada a modo LowPower
                LowPowerFlags |= BIT0;
            }
            
            // Conversion ASCII de temperatura
            if( (Flags2 & BIT2 ) && (!( datosListosFlags & BIT2)) ){

                tempSensorBinaryToASCII(BMP085_UT, PFSW_TransPackage, TEMP_SENSOR_OFFSET);

                //Indicar que ya se convirtio la presion ya esta en el paquete
                datosListosFlags |= BIT2;
            }

            // Conversion  ASCII de presion
            if( (Flags2 & BIT3) && (! ( datosListosFlags & BIT3 ))){


                presSensorBinaryToASCII(BMP085_UP, PFSW_TransPackage, PRES_SENSOR_OFFSET);


                datosListosFlags |= BIT3;
            }

            // Conversion ASCII de ACC
            //  ¿Esta lista la muestra?  ¿Aun no se encuentra en PFSW_TransPackage?
            if( (Flags2 & BIT4) &&          (! ( datosListosFlags & BIT4)) ){
              
                accSensorXBinaryToASCII(ACC_SENSOR_X, PFSW_TransPackage, ACC_X_OFFSET);
                accSensorXBinaryToASCII(ACC_SENSOR_Y, PFSW_TransPackage, ACC_Y_OFFSET);
                accSensorXBinaryToASCII(ACC_SENSOR_Z, PFSW_TransPackage, ACC_Z_OFFSET);
                // Indicar que ACC esta lista en paquete de datos
                datosListosFlags |= BIT4;
                
            }

                            // ¿Tiempo listo?          ¿Aun no esta en CFSW_TransPackage?
            if( (Flags4 & BIT4) && (!( datosListosFlags & BIT6 )) ){

                // Convertir mission time a ASCII y colocar en paquete de datos
                rtcBinaryToASCII( missionTimeSeconds, PFSW_TransPackage, MISSION_TIME_OFFSET );

                //  Indicar que ya esta listo en paquete de datos
                datosListosFlags |= BIT6;

            }

           //    ¿Voltaje listo?                ¿Temperatura Lista?              ¿Presion Listo?
            if( (datosListosFlags & BIT1) && (datosListosFlags & BIT2) && (datosListosFlags & BIT3)
           //      ¿ACC Listo?                 ¿Mission Time Listo?            ¿PACKET NUMBER LISTO? 
             && (datosListosFlags & BIT4) && ( datosListosFlags & BIT6 ) && ( datosListosFlags & BIT5 ) 
           //     ¿XBEE NO LISTO?  
             && (!(Flags4 & BIT1)) ){
                
                despertarXBEE();
                
            }
            
            //    Verificar:
            //    ¿XBEE_TX_EN?         ¿TX Activa?         ¿XBEE_Disponible?
            if( (Flags1 & BIT1)  && (!(Flags1 & BIT4 )) && (Flags1 & BIT5)) {   
                

                //Habilitar entrada a modo sleep para CCR1
                LowPowerFlags |= BIT5;
                

                startXBEETransmission();      
       
                /*
                //Requerir nueva indicacion de paquete listo
                datosListosFlags &= ~(BIT5 + BIT4 + BIT3 + BIT2 + BIT1 + BIT0);
                

                //Resetear bandera de datos para conversion a ASCII listos
                // BIT2: BMP085 UT
                // BIT4: ACC Sensor
                // BIT3: BMP085 UP
                // BIT0: Voltaje
                Flags2 &= ~(BIT4 + BIT3 + BIT2 + BIT0);
                

                // Resetear banderas de inicio de procesos de muestreo
                // para siguiente ronda de muestreo
                procesoIniciadoFlags &= ~(BIT0);    //Bandera ADC
                //Flags1 &= ~(BIT6 + BIT7);                  // BMP085_UT, BMP085_UP
                */
                    
            }
            

            //  Iniciar TA0CCR4 para SLEEP XBEE
            if(  Flags4 & BIT6 ){

                // Iniciar  Timer de desactivacion de XBEE
                setTimerA0_CCR2(1531);

                // Ya no es turno de XBEE SLEEP
                Flags4 &= ~BIT6;

            }

            //  TUrno de dormir XBEE
            if( Flags4 & BIT7 ){

                //  Habilitar SLEEP de parte de TA0CCR2
                LowPowerFlags |= BIT4;

                // Solicitar modo sleep a XBEE
                P3OUT |= BIT2;

                Flags4 &= ~BIT7;

            }
            
            // Procesamiento posterior a Transmision XBEE
            //   
            if( Flags3 & BIT0 ){
              
                // Procesamiento posterior a XBEE TX permite modo sleep
                LowPowerFlags |= BIT2;

                // Procesamiento de TIMERA1_CCR2, I2C_TX, I2C_RX  permite modo sleep
                LowPowerFlags |= (BIT1 + BIT3);
                LowPowerFlags2 |= (BIT1);
                
                /*
                //Apagar LED de 1s
                P1OUT &= ~(BIT2);
                
                //
                Flags3 &= ~BIT0;


                // Indicar que procesamiento principal cada segundo termina aqui
                Flags3 &= ~BIT3;

                //Requerir nueva indicacion de paquete listo
                datosListosFlags &= ~(BIT5 + BIT4 + BIT3 + BIT2 + BIT1 + BIT0);

                //Resetear bandera de datos para conversion a ASCII listos
                // BIT2: BMP085 UT
                // BIT4: ACC Sensor
                // BIT3: BMP085 UP
                // BIT0: Voltaje
                Flags2 &= ~(BIT4 + BIT3 + BIT2 + BIT0);
                

                // Resetear banderas de inicio de procesos de muestreo
                // para siguiente ronda de muestreo
                procesoIniciadoFlags &= ~(BIT0);    //Bandera ADC
                */

                savePacketCount();
                //guardarPaqueteMemoriaExterna();
                
            }

            if(Flags4 & BIT2){
                  
                // Procesamiento de TIMERA1_CCR2, I2C_TX, I2C_RX  permite modo sleep
                LowPowerFlags |= (BIT1 + BIT3);
                LowPowerFlags2 |= (BIT1);

                // Guardar datos en memoria externa
                guardarPaqueteMemoriaExterna();                
                
            }            
            
            // Verificar si se puede entrar a modo LPM1
            //   ADC PROC CALL              I2C_TX PROC CALL         XBEE_TX PROC CALL           I2C_RX PROC CALL         
            if((LowPowerFlags & BIT0) && (LowPowerFlags & BIT1) && ( LowPowerFlags & BIT2 ) && (LowPowerFlags & BIT3)

            //      TA0CCR2_TMR PROC CALL    TA0CCR1_TMR PROC CALL      TA0CCR3_TMR PROC CALL      TA0CCR4_TMR PROC CALL
               && (LowPowerFlags & BIT4) && (LowPowerFlags & BIT5) && (LowPowerFlags & BIT6) &&  (LowPowerFlags & BIT7)
            //      TA1CCR1_TMR PROC CALL     TA1CCR2_TMR PROC CALL        TA2CCR1_TMR PROC CALL
               && (LowPowerFlags2 & BIT0) && (LowPowerFlags2 & BIT1)  && (LowPowerFlags2 & BIT2)   ) {
                //Entrar a modo LPM1 con Interrupciones
                // CPU = 0FF, ACLK Active, SMCLK Active and DCO active 'cause sources SMCLK
                P1OUT |= BIT3;
                _BIS_SR(LPM1_bits + GIE);
                P1OUT &= ~(BIT3);
                //_BIS_SR(GIE);
            }
        }

        //  TUrno de dormir XBEE
        if( Flags4 & BIT7 ){

            //  Habilitar SLEEP de parte de TA0CCR2
            LowPowerFlags |= BIT4;

            // Solicitar modo sleep a XBEE
            P3OUT |= BIT2;

            // Indicar que ya no es turno de dormir XBEE
            Flags4 &= ~BIT7;

            // Entrar nuevamente a modo SLEEP de MCU
            _BIS_SR(LPM1_bits + GIE);

        }        


        // Verificar si el paquete recibido de PC (UCA1RXBUF)
        if( Flags3 & BIT1 ){
            // Indicar que ya proceso el dato
            Flags3 &= ~(BIT1);
            P1OUT ^= BIT3;
            // Verificar si se solicito modo MONITOREO
            if(PC_RXBUF[0] == 'M'){
                modo = 0xAA;                
                // Desplegar mensaje de entrada a modo monitoreo
                if( ! (MFlags1 & BIT1)){
                    startPCTransmission(enterMonitorMode, 10);
                }
                // Esperar a que transmision termine
                while(MFlags1 & BIT1); 


                //  Despertar a XBEE utilizando SLEEP_RQ
                P3OUT &= ~(BIT2);

            }
            // Resetear puntero para almacenar siempre en posicion 0
            PC_RXBUF_POINTER = 0;
        }
        

      }
      
      // Verificar si el paquete recibido de PC (UCA1RXBUF)
        if( Flags3 & BIT1 ){
            // Indicar que ya proceso el dato
            Flags3 &= ~(BIT1);
            P1OUT ^= BIT3;
            // Verificar si se solicito modo MONITOREO
            if(PC_RXBUF[0] == 'M'){
                modo = 0xAA;                
                // Desplegar mensaje de entrada a modo monitoreo
                if( ! (MFlags1 & BIT1)){
                    startPCTransmission(enterMonitorMode, 10);
                }
                // Esperar a que transmision termine
                while(MFlags1 & BIT1); 


                //  Despertar a XBEE utilizando SLEEP_RQ
                P3OUT &= ~(BIT2);

            }
            // Resetear puntero para almacenar siempre en posicion 0
            PC_RXBUF_POINTER = 0;
        }
      
      
      
      
               
        // Modo de Monitoreo
        while(modo == 0xAA){
            //  Despertar a XBEE utilizando SLEEP_RQ
            P3OUT &= ~(BIT2);
        
            // Utilizar axiliarmente bandera de habilitacion de sensores
            // para blinkear
            if(Flags1 & BIT1){
                P1OUT ^= BIT3;
                Flags1 &= ~(BIT1);
            }
            
            // Si se recibio dato por PC_RX
            if(MFlags1 & BIT0){
              
                // Indicar que ya se proceso dato
                MFlags1 &= ~(BIT0);
                
                // Resetear puntero de buffer
                PC_RXBUF_POINTER = 0;
                
                switch(PC_RXBUF[0]){

                    // Muestrear sensor de voltaje
                    case 'V':

                        // Tomar una muestra de sensor de voltaje
                        sampleADC();

                        // Esperar a que la muestra sea tomada
                        while( !(Flags2 & BIT0) );
                        Flags2 &= ~BIT0;

                        // Convertir a ASCII y armar String
                        voltageBinaryToASCII(VOLTAJE_ADC, PC_PACKET, 0);

                        // Anadir indicador de fin de envio
                        PC_PACKET[4] = 0x0D;

                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 5);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        break;
                  
                    // Obtener constantes de calibracion
                    case 'N':
                        getCalBMP085();

                        bmp085CalWordBinaryToASCII_Signed(ac1, PC_PACKET, 1);
                        PC_PACKET[6]=0x2C;                                              
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 7);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        bmp085CalWordBinaryToASCII_Signed(ac2, PC_PACKET, 1);
                        PC_PACKET[6]=0x2C;                                              
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 7);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);


                        bmp085CalWordBinaryToASCII_Signed(ac3, PC_PACKET, 1);
                        PC_PACKET[6]=0x2C;                                              
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 7);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);


                        bmp085CalWordBinaryToASCII_Unsigned(ac4, PC_PACKET, 1);
                        PC_PACKET[6]=0x2C;                                              
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 7);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);
                        
                        bmp085CalWordBinaryToASCII_Unsigned(ac5, PC_PACKET, 1);
                        PC_PACKET[6]=0x2C;                                              
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 7);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        bmp085CalWordBinaryToASCII_Unsigned(ac6, PC_PACKET, 1);
                        PC_PACKET[6]=0x2C;                                              
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 7);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        bmp085CalWordBinaryToASCII_Signed(b1, PC_PACKET, 1);
                        PC_PACKET[6]=0x2C;                                              
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 7);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        bmp085CalWordBinaryToASCII_Signed(b2, PC_PACKET, 1);
                        PC_PACKET[6]=0x2C;                                              
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 7);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        bmp085CalWordBinaryToASCII_Signed(mb, PC_PACKET, 1);
                        PC_PACKET[6]=0x2C;                                              
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 7);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);                        

                        bmp085CalWordBinaryToASCII_Signed(mc, PC_PACKET, 1);
                        PC_PACKET[6]=0x2C;                                              
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 7);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);
                        
                        bmp085CalWordBinaryToASCII_Signed(md, PC_PACKET, 1);
                        PC_PACKET[6]=0x0D;                                              
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 7);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);     

                        break;

                    // Muestrear sensor de aceleracion
                    case 'A':
                      
                        
                        // Indicar que aun no esta lista muestra de ACC (para rehabilitar muestreo)
                        Flags2 &= ~(BIT4);
                        // Verificar bandera de muestra lista
                        while ( !(Flags2 & BIT4)){
                            sampleACCSensor();
                        }
                        
                      
                        // Hacer conversiones ASCII y colocar en un paquete para enviarlo
                        // por PC_TX
                        accSensorXBinaryToASCII(ACC_SENSOR_X, PC_PACKET, 1);
                        accSensorXBinaryToASCII(ACC_SENSOR_Y, PC_PACKET, 6);
                        accSensorXBinaryToASCII(ACC_SENSOR_Z, PC_PACKET, 11);
                        

                        PC_PACKET[15] = 0x0D;

                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 16);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);
                        break;
                     
                    // Muestrear temperatura    
                    case 'T':
                      
                        Flags2 &= ~(BIT2);
                        while (!(Flags2 & BIT2)){                        
                            // Obtener Temperatura sin compensacion
                            getUT_BMP085();                     
                        }
                        



                        tempSensorBinaryToASCII(BMP085_UT, PC_PACKET, 0);

                        // Anadir caracter de final dato
                        PC_PACKET[5]=0x0D;  
                      
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 6);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);   
                      
                        break;  
                    
                    //Muestrar Presion
                    case 'P':
                      
                        Flags2 &= ~(BIT3);
                        while (!(Flags2 & BIT3)){                        
                            // Obtener Temperatura sin compensacion
                            getUP_BMP085();                      
                        }
                      


                        presSensorBinaryToASCII(BMP085_UP, PC_PACKET, 0);

                        // Anadir simbolo de final de mensaje
                        PC_PACKET[5] = 0x0D;                      


                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 6);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);   
                      
                        break;  
                    
                    // Transmitir cuenta de paquetes
                    case 'S':                        // Actualizar Packet Count
                        do{
                            getPacketCount();
                        }while(XBEE_PACKET_RETRIEVE_PROC);
                        // Reducir packetCount por que getPacketCount() aumenta en 1
                        XBEE_TXBUF_COUNTER--;
                         
                        packetCountBinaryToASCII(XBEE_TXBUF_COUNTER, PC_PACKET, 0);
                        

                        PC_PACKET[4] =0x0D;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 5);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);             
                      
                        break;

                    case 'C':


                        // Actualizar mission time
                        do{
                          getMissionTime();
                        }while( RTC_getMissionTime_PROC );

                        rtcBinaryToASCII(missionTimeSeconds, PC_PACKET, 0);

                        PC_PACKET[4] = 0x0D;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 5);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);                

                        break;                          
                
                    // Verificar si se indica salida de modo monitoreo   
                    case 'E':                        
                        // Reconfigurar variables y flags para entrar a modo de vuelo
                        Flags1 = 0;
                        Flags2 = 0;
                        Flags3 = 0;
                        Flags4 = 0;
                        datosListosFlags = 0;
                        // Comienza con valor 7 despues de un reset
                        procesoTerminadoFlags = 7;
                        procesoIniciadoFlags = 0;
                        // Permitir entrada a LPM 
                        LowPowerFlags = 255;
                        procesoTerminadoFlags2 = 0;  
                        LowPowerFlags2 = 0xFF;              
                        
                        // Salir de modo de monitoreo
                        modo = 0x55;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(exitMonitorMode, 6);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);                          
                        // Configurar el sensor para modo de VUELO
                        configureACCSensor(0x01);

                        //   Dormir XBEE
                        P3OUT |= (BIT2);


                        break;

                    // Self test acelerometro
                    case 'L':
                      

                        // Configurar el sensor para modo de prueba
                        configureACCSensor(0x0B);

                        // Esperar 1.1ms
                        setTimerA0_CCR3(11);
                        while(!( procesoTerminadoFlags & BIT4));

                        // Tomar 100 muestras y enviarlas a PC
                        for(dummy_counter1 = 0; dummy_counter1 < 100; dummy_counter1++){

                            // Tomar muestra
                            do{
                                sampleACCSensor();
                            }while(ACC_SENSOR_PROCESS_STATE);

                            // Convertir a ASCII y colocar en paquete a enviar a PC
                            accSensorXBinaryToASCII(ACC_SENSOR_X, PC_PACKET, 1);
                            accSensorXBinaryToASCII(ACC_SENSOR_Y, PC_PACKET, 6);
                            accSensorXBinaryToASCII(ACC_SENSOR_Z, PC_PACKET, 11);

                            if(dummy_counter1<99){
                                //Separar por coma
                                PC_PACKET[15]=',';
                            }else{
                                // Indicador de final de paquete
                                PC_PACKET[15]=0x0D;
                            }

                            if( ! (MFlags1 & BIT1)){
                                startPCTransmission(PC_PACKET, 16);
                            }
                            // Esperar a que transmision termine
                            while(MFlags1 & BIT1);  
                        }
                        
                        // Encender modo self test interno al sensor
                        configureACCSensor(0x8B);
                        
                        // Esperar 1.1ms
                        setTimerA0_CCR3(11);
                        while(!( procesoTerminadoFlags & BIT4));
                        
                        // Tomar 100 muestras y enviarlas a PC
                        for(dummy_counter1 = 0; dummy_counter1 < 100; dummy_counter1++){

                            // Tomar muestra
                            do{
                                sampleACCSensor();
                            }while(ACC_SENSOR_PROCESS_STATE);

                            // Convertir a ASCII y colocar en paquete a enviar a PC
                            accSensorXBinaryToASCII(ACC_SENSOR_X, PC_PACKET, 1);
                            accSensorXBinaryToASCII(ACC_SENSOR_Y, PC_PACKET, 6);
                            accSensorXBinaryToASCII(ACC_SENSOR_Z, PC_PACKET, 11);

                            if(dummy_counter1<99){
                                //Separar por coma
                                PC_PACKET[15]=',';
                            }else{
                                // Indicador de final de paquete
                                PC_PACKET[15]=0x0D;
                            }

                            if( ! (MFlags1 & BIT1)){
                                startPCTransmission(PC_PACKET, 16);
                            }
                            // Esperar a que transmision termine
                            while(MFlags1 & BIT1);  
                        }

                        // Apagar modo Self-test escribiendo 0x0B de nuevo
                        configureACCSensor(0x0B);
                        
                        break;

                    // Armar paquete y enviar a GCS por cable
                    case 'J':

                        armarPaquetePFSW(PFSW_TransPackage);

                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PFSW_TransPackage, PFSW_TransPackage_Length);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        break;                        

                    // Armar paquete, enviar a GCS por cable y guardar en memoria
                    case 'K':


                        armarPaquetePFSW(PFSW_TransPackage);

                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PFSW_TransPackage, PFSW_TransPackage_Length);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        do{
                            guardarPaqueteMemoriaExterna();
                        }while( guardarPaqueteCFSW_PROC != 0 );
                        break;



                        break;

                    // Armar paquete, enviar a GCS por XBEE y guardar en memoria
                    case 'H':


                        armarPaquetePFSW(PFSW_TransPackage);

                        if( ! (Flags1 & BIT4) ){
                            startXBEETransmission2(PFSW_TransPackage, PFSW_TransPackage_Length);;
                        }
                        // Esperar a que transmision termine
                        while(Flags1 & BIT4);

                        do{
                            guardarPaqueteMemoriaExterna();
                        }while( guardarPaqueteCFSW_PROC != 0 );
                        


                        break;

                    // Obtener datos almacenados en memoria
                    case 'O':

                        for(dummy_counter1 = 0; dummy_counter1 <= 0x3FFF; dummy_counter1++){
                                
                          EXTERNAL_MEMORY_TX_BUFFER[1]= *((unsigned char *)&dummy_counter1);
                          EXTERNAL_MEMORY_TX_BUFFER[0]= *(((unsigned char *)&dummy_counter1)+1);
                                
                            // Leer memoria en la posicion dummy_counter1
                            do
                            {
                              readByteExternalEEPROM2(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER);

                            } while ( EXTERNAL_MEMORY_BYTEREAD_PROC != 0);
                            

                            if( ! (MFlags1 & BIT1)){
                                startPCTransmission(SENSOR_RXBUF, 1);
                            }
                            // Esperar a que transmision termine
                            while(MFlags1 & BIT1);

                        }

                        // Por ultimo enviar "/n" seguido de "/r"
                        PC_PACKET[0]=0x0A;
                        PC_PACKET[1]=0x0D;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 2);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        break;

                    // Borrar memoria externa
                    case 'D':

                        eraseExternalMemoryComplete();

                        // Enviar Acknowledgement
                        PC_PACKET[0]='A';
                        PC_PACKET[1]= 0x0D;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 2);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);


                        break;

                    // Inicializar memoria externa
                    case 'I':

                        // 
                        initExternalMemory();

                        do{
                            setMissionTime();
                        }while(RTC_setMissionTime_PROC);

                        // Enviar Acknowledgement
                        PC_PACKET[0]='A';
                        PC_PACKET[1]= 0x0D;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 2);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        break;    
                    
                    default:
                        // Enviar Acknowledgement
                        PC_PACKET[0]='E';
                        PC_PACKET[1]= 0x0D;

                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 2);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);
                        break;
                }
            }
        }
    }  
}